# Array Array 对象是用于构造数组的全局对象,数组是类似于列表的高阶对象。 ## 构造函数 ### new \(...items : T\[]) : T[]@Constructor(...items) ::: warning 注意事项 与JS中的`Array` 不同,`UTS`不支持的指定长度初始化Array的写法 ```ts let arr = new Array(10) ``` 上面的代码在不同的平台的表现有差异: - web平台 一个长度为10的数组,每一个元素都是 undefined - Android/ios平台 一个长度为1的数组,其元素为 数字10 ::: ## 实例属性 ### length 边界情况说明: - 在不同平台上,数组的长度限制不同,超出限制会导致相应的错误或异常 * 编译至 JavaScript 平台时,最大长度为 2^32 - 1,超出限制会报错:`Invalid array length`。 * 编译至 Kotlin 平台时,最大长度受系统内存的限制,超出限制报错:`java.lang.OutOfMemoryError: Failed to allocate a allocation until OOM`。 * 编译至 Swift 平台时,最大长度也受系统内存的限制,目前超出限制没有返回信息。 ## 实例方法 ### toString() ### add(item) ### toLocaleString() ### joinToString(separator) ### find(predicate, thisArg?) ### find(predicate, thisArg?) ### find(predicate, thisArg?) ### findIndex(predicate, thisArg?) ### findIndex(predicate, thisArg?) ### findIndex(predicate, thisArg?) ### fill(value, start?, end?) 需要注意的是,截止HBuilder 4.22 部分平台尚不支持[根据元素个数构造`Array`的写法](https://doc.dcloud.net.cn/uni-app-x/uts/buildin-object-api/array.html#constructor) 所以下面的代码在 部分平台可能不符合预期 ```ts new Array(20).fill(0) ``` 可以使用下面的代码替代 ```ts let b = Array() for(let i = 0; i < 20; i++){ b.add(0) } ``` ### copyWithin(target, start?, end?) ### pop() ### push(...items) ### concat(...items) ### concat(...items) ### join(separator?) ### reverse() ### shift() ### slice(start?, end?) ### sort(compareFn?) **平台差异性** 在android平台,一定不能忽略两个对比元素相等的场景,否则可能会出现`java.lang.IllegalArgumentException: Comparison method violates its general contract!‌` ``` a.sort((a, b) : number => { // 这里的判断不能省略 if(a.compareTo(b) == 0){ return 0 } return a - b }) ``` ### splice(start, deleteCount, ...items) ### unshift(...items) ### indexOf(searchElement, fromIndex?) ### lastIndexOf(searchElement, fromIndex?) ### every(predicate, thisArg?) ### every(predicate, thisArg?) ### every(predicate, thisArg?) ### every(predicate, thisArg?) ### some(predicate, thisArg?) ### some(predicate, thisArg?) ### some(predicate, thisArg?) ### forEach(callbackfn, thisArg?) > 特别注意: > 不可在 forEach 的 callbackFn 里添加或者删除原数组元素,此行为是危险的,在 Android 平台会造成闪退,在 iOS 平台会造成行为不符合预期。如果想实现该效果,请用 while 循环。 ```ts const array1 = ['a', 'b', 'c']; array1.forEach(element => { console.log(element) array1.pop() // 此行为在 Android 平台会造成闪退,在 iOS 平台会输出 'a', 'b', 'c', 而 JS 会输出 'a', 'b' }); // 如果想让上述行为正常运行,可以用 while 循环实现: let array1 = ['a', 'b', 'c']; let index = 0; while (index < array1.length) { console.log(array1[index]); array1.pop(); index += 1; } ``` ### forEach(callbackfn, thisArg?) ### forEach(callbackfn, thisArg?) ### map(callbackfn, thisArg?) ### map(callbackfn, thisArg?) ### map(callbackfn, thisArg?) ### filter(predicate, thisArg?) ### filter(predicate, thisArg?) ### filter(predicate, thisArg?) ### filter(predicate, thisArg?) ### reduce(callbackfn) ### reduce(callbackfn) ### reduce(callbackfn, initialValue) ### reduce(callbackfn, initialValue) ### reduce(callbackfn, initialValue) ### reduce(callbackfn, initialValue) ### reduceRight(callbackfn) ### reduceRight(callbackfn) ### reduceRight(callbackfn) ### reduceRight(callbackfn, initialValue) ### reduceRight(callbackfn, initialValue) ### reduceRight(callbackfn, initialValue) ### reduceRight(callbackfn, initialValue) ### isArray(arg) ### includes(searchElement, fromIndex?) ### toKotlinList() ## Android 平台方法 * 目前 Array 类型编译到 `kotlin` 为 `io.dcloud.uts.UTSArray`, 该类继承自 `java.util.ArrayList`,所有`java` /`kotlin` 为其提供的扩展函数(如:`toTypedArray` 等),均可以正常调用。 ::: preview > UTS ```ts let utsArray = ["1",2,3.0] // UTSArray 分别转换为 Java Array / Kotlin Array let javaArray = utsArray.toTypedArray(); let kotlinArray = utsArray.toKotlinList() // 从Java Array 转换为 UTSArray let convertArrayFromJava = Array.fromNative(javaArray); // 从Kotlin Array 转换为 UTSArray let convertArrayFromKotlin = Array.fromNative(kotlinArray); ``` > Kotlin ```kotlin val utsArray = utsArrayOf("1",2,3.0) // UTSArray 分别转换为 Java Array / Kotlin Array val javaArray = utsArray.toTypedArray(); val kotlinArray = utsArray.toKotlinList() // 从Java Array 转换为 UTSArray val convertArrayFromJava = UTSArray.fromNative(javaArray); // 从Kotlin Array 转换为 UTSArray val convertArrayFromKotlin = UTSArray.fromNative(kotlinArray); ``` ::: 更多平台专属Array 参考[文档](https://doc.dcloud.net.cn/uni-app-x/uts/data-type.html#kotlin%E4%B8%93%E6%9C%89%E6%95%B0%E7%BB%84%E7%B1%BB%E5%9E%8B) ## 常见操作 - 创建数组 ```ts const fruits = ['Apple', 'Banana'] console.log(fruits.length) ``` - 通过索引访问数组元素 ```ts const first = fruits[0] // Apple const last = fruits[fruits.length - 1] // Banana ``` - 遍历数组 ```ts fruits.forEach(function(item, index, array) { console.log(item, index) }) // Apple 0 // Banana 1 ``` - 注意:数组遍历不推荐使用 for in 语句,因为在 ts 中 for in 遍历的是数组的下标,而在 Swift 和 Kottlin 中遍历的是数组的元素,存在行为不一致。 - 添加元素到数组的末尾 ```ts const newLength = fruits.push('Orange') // ["Apple", "Banana", "Orange"] ``` - 删除数组末尾的元素 ```ts const last = fruits.pop() // remove Orange (from the end) // ["Apple", "Banana"] ``` - 删除数组头部元素 ```ts const first = fruits.shift() // remove Apple from the front // ["Banana"] ``` - 添加元素到数组的头部 ```ts const newLength = fruits.unshift('Strawberry') // add to the front // ["Strawberry", "Banana"] ``` - 找出某个元素在数组中的索引 ```ts fruits.push('Mango') // ["Strawberry", "Banana", "Mango"] const pos = fruits.indexOf('Banana') // 1 ``` - 通过索引删除某个元素 ```ts const removedItem = fruits.splice(pos, 1) // this is how to remove an item // ["Strawberry", "Mango"] ``` - 从一个索引位置删除多个元素 ```ts const vegetables = ['Cabbage', 'Turnip', 'Radish', 'Carrot'] console.log(vegetables) // ["Cabbage", "Turnip", "Radish", "Carrot"] const pos = 1 const n = 2 const removedItems = vegetables.splice(pos, n) // this is how to remove items, n defines the number of items to be removed, // starting at the index position specified by pos and progressing toward the end of array. console.log(vegetables) // ["Cabbage", "Carrot"] (the original array is changed) console.log(removedItems) // ["Turnip", "Radish"] ``` - 复制一个数组 ```ts const shallowCopy = fruits.slice() // this is how to make a copy // ["Strawberry", "Mango"] ``` ### 访问数组元素 数组的索引是从 0 开始的,第一个元素的索引为 0,最后一个元素的索引等于该数组的 长度 减 1。 如果指定的索引是一个无效值,将会抛出 IndexOutOfBoundsException 异常 下面的写法是错误的,运行时会抛出 SyntaxError 异常,而原因则是使用了非法的属性名: ```ts console.log(arr.0) // a syntax error ```