# Array Array 对象是用于构造数组的全局对象,数组是类似于列表的高阶对象。 ## 构造函数 ### new \(...items : T\[]) : T[]@Constructor(...items)_0 ```ts /** * 用法1:创建数组时需要指定类型,即:Array */ let arrA = new Array() /** * 用法2:创建数组时根据初始元素,推导出类型为:Array */ let arrB = new Array(32,87,32) ``` ::: warning 注意事项 与JS中的`Array` 不同,`UTS`不支持的指定长度初始化Array的写法 ```ts let arr = new Array(10) ``` 上面的代码在不同的平台的表现有差异: - web平台 一个长度为10的数组,每一个元素都是 undefined - Android/ios平台 一个长度为1的数组,其元素为 数字10 ::: ## 实例属性 ### length ```ts const clothing = ['shoes', 'shirts', 'socks', 'sweaters']; console.log(clothing.length); // expected output: 4 ``` 边界情况说明: - 在不同平台上,数组的长度限制不同,超出限制会导致相应的错误或异常 * 编译至 JavaScript 平台时,最大长度为 2^32 - 1,超出限制会报错:`Invalid array length`。 * 编译至 Kotlin 平台时,最大长度受系统内存的限制,超出限制报错:`java.lang.OutOfMemoryError: Failed to allocate a allocation until OOM`。 * 编译至 Swift 平台时,最大长度也受系统内存的限制,目前超出限制没有返回信息。 ## 实例方法 ### find(predicate, thisArg?) ```ts const array1 = [5, 12, 8, 130, 44]; const found = array1.find((element:number):boolean => element > 10); console.log(found); // expected output: 12 ``` ### findIndex(predicate, thisArg?) ```ts const array1 = [5, 12, 8, 130, 44]; const isLargeNumber = (element:number):boolean => element > 13; console.log(array1.findIndex(isLargeNumber)); // expected output: 3 ``` ### fill(value, start?, end?) ```ts const array1 = [1, 2, 3, 4]; // fill with 0 from position 2 until position 4 console.log(array1.fill(0, 2, 4)); // expected output: [1, 2, 0, 0] // fill with 5 from position 1 console.log(array1.fill(5, 1)); // expected output: [1, 5, 5, 5] console.log(array1.fill(6)); // expected output: [6, 6, 6, 6] ``` 需要注意的是,截止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?) ```ts const array1 = ['a', 'b', 'c', 'd', 'e']; // copy to index 0 the element at index 3 console.log(array1.copyWithin(0, 3, 4)); // expected output: Array ["d", "b", "c", "d", "e"] // copy to index 1 all elements from index 3 to the end console.log(array1.copyWithin(1, 3)); // expected output: Array ["d", "d", "e", "d", "e"] ``` ### pop() ```ts const plants = ['broccoli', 'cauliflower', 'cabbage', 'kale', 'tomato']; console.log(plants.pop()); // expected output: "tomato" console.log(plants); // expected output: Array ["broccoli", "cauliflower", "cabbage", "kale"] plants.pop(); console.log(plants); // expected output: Array ["broccoli", "cauliflower", "cabbage"] ``` ### push(...items) ```ts const animals = ['pigs', 'goats', 'sheep']; const count = animals.push('cows'); console.log(count); // expected output: 4 console.log(animals); // expected output: Array ["pigs", "goats", "sheep", "cows"] animals.push('chickens', 'cats', 'dogs'); console.log(animals); // expected output: Array ["pigs", "goats", "sheep", "cows", "chickens", "cats", "dogs"] ``` ### concat(...items) ```ts const array1 = ['a', 'b', 'c']; const array2 = ['d', 'e', 'f']; const array3 = array1.concat(array2); console.log(array3); // expected output: Array ["a", "b", "c", "d", "e", "f"] ``` ### concat(...items) ### join(separator?) ```ts const elements = ['Fire', 'Air', 'Water']; console.log(elements.join()); // expected output: "Fire,Air,Water" console.log(elements.join('')); // expected output: "FireAirWater" console.log(elements.join('-')); // expected output: "Fire-Air-Water" ``` ### reverse() ### shift() ```ts const array1 = [1, 2, 3]; const firstElement = array1.shift(); console.log(array1); // expected output: Array [2, 3] console.log(firstElement); // expected output: 1 ``` ### slice(start?, end?) ```ts const animals = ['ant', 'bison', 'camel', 'duck', 'elephant']; console.log(animals.slice(2)); // expected output: Array ["camel", "duck", "elephant"] console.log(animals.slice(2, 4)); // expected output: Array ["camel", "duck"] console.log(animals.slice(1, 5)); // expected output: Array ["bison", "camel", "duck", "elephant"] console.log(animals.slice(-2)); // expected output: Array ["duck", "elephant"] console.log(animals.slice(2, -1)); // expected output: Array ["camel", "duck"] console.log(animals.slice()); // expected output: Array ["ant", "bison", "camel", "duck", "elephant"] ``` ### sort(compareFn?) ```ts const array2 = [5, 1, 4, 2, 3]; array2.sort((a: number, b: number):number => a - b); // expect(array2).toEqual([1, 2, 3, 4, 5]); ``` **平台差异性** 在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) ```ts const months = ['Jan', 'March', 'April', 'June']; months.splice(1, 0, 'Feb'); // inserts at index 1 console.log(months); // expected output: Array ["Jan", "Feb", "March", "April", "June"] months.splice(4, 1, 'May'); // replaces 1 element at index 4 console.log(months); // expected output: Array ["Jan", "Feb", "March", "April", "May"] ``` ### unshift(...items) ```ts const array1 = [1, 2, 3]; console.log(array1.unshift(4, 5)); // expected output: 5 console.log(array1); // expected output: Array [4, 5, 1, 2, 3] ``` ### indexOf(searchElement, fromIndex?) ```ts const beasts = ['ant', 'bison', 'camel', 'duck', 'bison']; console.log(beasts.indexOf('bison')); // expected output: 1 // start from index 2 console.log(beasts.indexOf('bison', 2)); // expected output: 4 console.log(beasts.indexOf('giraffe')); // expected output: -1 ``` ### lastIndexOf(searchElement, fromIndex?) ```ts const animals = ['Dodo', 'Tiger', 'Penguin', 'Dodo']; console.log(animals.lastIndexOf('Dodo')); // expected output: 3 console.log(animals.lastIndexOf('Tiger')); // expected output: 1 ``` ### every(predicate, thisArg?) ```ts const isBelowThreshold = (currentValue:number):boolean => currentValue < 40; const array1 = [1, 30, 39, 29, 10, 13]; console.log(array1.every(isBelowThreshold)); // expected output: true ``` ### every(predicate, thisArg?)_1 ### every(predicate, thisArg?)_2 ### every(predicate, thisArg?)_3 ### some(predicate, thisArg?) ```ts const array = [1, 2, 3, 4, 5]; // checks whether an element is even const even = (element:number):boolean=> element % 2 == 0; console.log(array.some(even)); // expected output: true ``` ### some(predicate, thisArg?)_1 ### some(predicate, thisArg?)_2 ### forEach(callbackfn, thisArg?) ```ts const array1 = ['a', 'b', 'c']; array1.forEach(element => console.log(element)); // expected output: "a" // expected output: "b" // expected output: "c" ``` > 特别注意: > 不可在 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; } ``` ### map(callbackfn, thisArg?) ```ts const array1 = [1, 4, 9, 16]; // pass a function to map const map1 = array1.map((x:number):number => x * 2); console.log(map1); // expected output: Array [2, 8, 18, 32] ``` ### filter(predicate, thisArg?) ```ts const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present']; const result = words.filter((word:string):boolean => word.length > 6); console.log(result); // expected output: Array ["exuberant", "destruction", "present"] ``` ### reduce(callbackfn) ```ts const array1 = [1, 2, 3, 4]; // 0 + 1 + 2 + 3 + 4 const initialValue = 0; const sumWithInitial = array1.reduce( (previousValue:number, currentValue:number):number => previousValue + currentValue, initialValue ); console.log(sumWithInitial); // expected output: 10 ``` ### reduceRight(callbackfn) ### isArray(arg) ```ts console.log(Array.isArray([1, 3, 5])); // Expected output: true console.log(Array.isArray('[]')); // Expected output: false console.log(Array.isArray(new Array(5))); // Expected output: true console.log(Array.isArray(new Int16Array([15, 33]))); // Expected output: false ``` ### includes(searchElement, fromIndex?) ### toKotlinList() ## Android 平台方法 * 目前 Array 类型编译到 `kotlin` 为 `io.dcloud.uts.UTSArray`, 该类继承自 `java.util.ArrayList`,所有`java` /`kotlin` 为其提供的扩展函数(如:`toTypedArray` 等),均可以正常调用。 更多平台专属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 ```