JS 数组操作总结
数组的创建方式
1、构造函数方式
var arr = new Array();//[]
var arr = new Array(2);//[empty*2]
2、数组字面两表示法
var arr = [];//[]
var arr = [2];//[2]
3、Array.of 方法 [ES6] [Array.of]=>MDN
Array.of()
方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。
Array.of()
和 Array
构造函数之间的区别在于处理整数参数:Array.of(7)
创建一个具有单个元素 7 的数组,而 Array(7)
创建一个长度为7的空数组(注意:这是指一个有7个空位的数组,而不是由7个undefined
组成的数组)。
Array.of(element0[, element1[, ...[, elementN]]])
Array.of(7); // [7] Array.of(1, 2, 3); // [1, 2, 3] Array(7); // [ , , , , , , ] Array(1, 2, 3); // [1, 2, 3]
Array 的 length 属性
数组中的length很有特点——他不是只读的。因此通过设置这个属性,可以从数组的末尾移除项或者向数组中添加新项。
var colors = ["red,"blue","green"]; colors.length = 2; alert(colors[2]);//undefined
检测数组
1、instanceof
对于一个网页或者一个全局作用域而言,使用instanceof操作符就能够得到满足的结果。
2、Array.isArray() [Array.isArray]=>MDN
Array.isArray() 用于确定传递的值是否是一个 Array
。
Array.isArray([1, 2, 3]); // true Array.isArray({foo: 123}); // false Array.isArray("foobar"); // false Array.isArray(undefined); // false
数组的转换
1、toString() [Array.prototype.toString]=>MDN
toString()
返回一个字符串,表示指定的数组及其元素。
arr.toString()
Array
对象覆盖了 Object
的 toString
方法。对于数组对象,toString
方法返回一个字符串,该字符串由数组中的每个元素的 toString()
返回值经调用 join()
方法连接(由逗号隔开)组成。例如,下面的代码创建了一个数组,然后使用 toString
方法把该数组转成一个字符串。
var monthNames = ['Jan', 'Feb', 'Mar', 'Apr']; var myVar = monthNames.toString(); // assigns "Jan,Feb,Mar,Apr" to myVar.
当一个数组被作为文本值或者进行字符串连接操作时,将会自动调用其 toString
方法。
2、join() [Array.prototype.join]=>MDN
join()
方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。
var elements = ['Fire', 'Wind', 'Rain']; console.log(elements.join()); // expected output: Fire,Wind,Rain console.log(elements.join('')); // expected output: FireWindRain console.log(elements.join('-')); // expected output: Fire-Wind-Rain
3、(拷贝)Array.from() [Array.from]=>MDN 【ES6】
方法从一个类似数组或可迭代对象中创建一个新的数组实例。
const bar = ["a", "b", "c"]; Array.from(bar); // ["a", "b", "c"] Array.from('foo'); // ["f", "o", "o"]
Array.from(arrayLike[, mapFn[, thisArg]])
参数
arrayLike
- 想要转换成数组的伪数组对象或可迭代对象。
mapFn (可选参数)
- 如果指定了该参数,新数组中的每个元素会执行该回调函数。
thisArg (可选参数)
- 可选参数,执行回调函数
mapFn
时this
对象。
返回值
一个新的数组实例
function f() { return Array.from(arguments); } f(1, 2, 3); // [1, 2, 3]
在ES5中是采用function(arrayLike){
return Array.prototype.slice.call(arrayLike);
}
数组的栈方法
1、push() [Array.prototype.push]=>MDN
push()
方法将一个或多个元素添加到数组的末尾,并返回新数组的长度。
arr.push(element1, ..., elementN)
2、pop() [Array.prototype.pop]=>MDN
pop()方法从数组中删除最后一个元素,并返回该元素的值。此方法更改数组的长度。
arr.pop()
数组的队列方法
1、shift() [Array.prototype.shift]=>MDN
shift()
方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。
let a = [1, 2, 3]; let b = a.shift(); console.log(a); // [2, 3] console.log(b); // 1
2、unshift() [Array.prototype.unshift]=>MDN
unshift()
方法将一个或多个元素添加到数组的开头,并返回新数组的长度。
let a = [1, 2, 3]; a.unshift(4, 5); console.log(a); // [4, 5, 1, 2, 3]
数组的重排序
1、reverse() [Array.prototype.reverse]=>MDN
reverse()
方法将数组中元素的位置颠倒。
第一个数组元素成为最后一个数组元素,最后一个数组元素成为第一个。
var array1 = ['one', 'two', 'three']; var reversed = array1.reverse(); console.log(array1); // expected output: Array ['three', 'two', 'one'] console.log(reversed); // expected output: Array ['three', 'two', 'one']
2、sort() [Array.prototype.sort]=>MDN
sort()
方法用就地( in-place )的算法对数组的元素进行排序,并返回数组。 sort 排序不一定是稳定的。默认排序顺序是根据字符串Unicode码点。
var fruit = ['cherries', 'apples', 'bananas']; fruit.sort(); // ['apples', 'bananas', 'cherries'] var scores = [1, 10, 21, 2]; scores.sort(); // [1, 10, 2, 21] // 注意10在2之前, // 因为在 Unicode 指针顺序中"10"在"2"之前 var things = ['word', 'Word', '1 Word', '2 Words']; things.sort(); // ['1 Word', '2 Words', 'Word', 'word'] // 在Unicode中, 数字在大写字母之前, // 大写字母在小写字母之前.
arr.sort() arr.sort(compareFunction)
如果指明了 compareFunction
,那么数组会按照调用该函数的返回值排序。即 a 和 b 是两个将要被比较的元素:
- 如果
compareFunction(a, b)
小于 0 ,那么 a 会被排列到 b 之前;
- 如果
compareFunction(a, b)
等于 0 , a 和 b 的相对位置不变。备注: ECMAScript 标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如 Mozilla 在 2003 年之前的版本);
- 如果
compareFunction(a, b)
大于 0 , b 会被排列到 a 之前。 compareFunction(a, b)
必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。
function compareNumbers(a, b) { return a - b; }
var numbers = [4, 2, 5, 1, 3]; numbers.sort((a, b) => a - b);
数组的操作方法
1、数组的拼接:concat() [Array.prototype.concat]=>MDN
concat()
方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
var array1 = ['a', 'b', 'c']; var array2 = ['d', 'e', 'f']; console.log(array1.concat(array2)); // expected output: Array ["a", "b", "c", "d", "e", "f"]
var new_array = old_array.concat(value1[, value2[, ...[, valueN]]])
2、数组的截取:slice() [Array.prototype.slice]=>MDN
slice()
方法返回一个从开始到结束(不包括结束)选择的数组的一部分浅拷贝到一个新数组对象。且原始数组不会被修改。
arr.slice();
// [0, end]
arr.slice(begin);
// [begin, end]
arr.slice(begin, end);
// [begin, end)
var 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"]
3、数组的插入,删除,替换: splite() [Array.prototype.splite]=>MDN
array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
start
- 指定修改的开始位置(从0计数)。如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位(从-1计数);若只使用start参数而不使用deleteCount、item,如:array.splice(start) ,表示删除[start,end]的元素。
deleteCount
可选- 整数,表示要移除的数组元素的个数。如果
deleteCount
是 0,则不移除元素。这种情况下,至少应添加一个新元素。如果deleteCount
大于start
之后的元素的总数,则从start
后面的元素都将被删除(含第start
位)。 - 如果deleteCount被省略,则其相当于(arr.length - start)。
item1, item2, ...
可选- 要添加进数组的元素,从
start
位置开始。如果不指定,则splice()
将只删除数组元素。
splice方法使用deleteCount参数来控制是删除还是添加:
start参数是必须的,表示开始的位置(从0计数),如:start=0从第一个开始;start>= array.length-1表示从最后一个开始。
①、从start位置开始删除[start,end]的元素。
array.splice(start)
②、从start位置开始删除[start,Count]的元素。
array.splice(start, deleteCount)
③、从start位置开始添加item1, item2, ...元素。
array.splice(start, 0, item1, item2, ...)
从第2位开始删除0个元素,插入“drum” var myFish = ["angel", "clown", "mandarin", "surgeon"]; //从第 2 位开始删除 0 个元素,插入 "drum" var removed = myFish.splice(2, 0, "drum"); //运算后的 myFish:["angel", "clown", "drum", "mandarin", "surgeon"] //被删除元素数组:[],没有元素被删除
var myFish = ['angel', 'clown', 'drum', 'mandarin', 'sturgeon']; var removed = myFish.splice(3, 1); //运算后的myFish:["angel", "clown", "drum", "sturgeon"] //被删除元素数组:["mandarin"]
从第2位开始删除所有元素 var myFish = ['angel', 'clown', 'mandarin', 'sturgeon']; var removed = myFish.splice(2); // 运算后的myFish :["angel", "clown"] // 被删除的元素数组: ["mandarin", "sturgeon"]
从第0位开始删除2个元素,然后插入"parrot","anemone"和"blue" var myFish = ['angel', 'clown', 'trumpet', 'sturgeon']; var removed = myFish.splice(0, 2, 'parrot', 'anemone', 'blue'); // 运算后的myFish: ["parrot", "anemone", "blue", "trumpet", "sturgeon"] // 被删除元素数组:["angel", "clown"]
4、数组填充:fill() [Array.prototype.fill]=>MDN
方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。
arr.fill(value[, start[, end]])
具体要填充的元素区间是 [start
, end
) , 一个半开半闭区间.
var 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]
5、数组内部的拷贝(复制) copyWithIn() [Array.prototype.copyWithIn]=>MDN
方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,而不修改其大小。
arr.copyWithin(target[, start[, end]])
var array1 = [1, 2, 3, 4, 5]; // place at position 0 the element between position 3 and 4 console.log(array1.copyWithin(0, 3, 4)); // expected output: Array [4, 2, 3, 4, 5] // place at position 1 the elements after position 3 console.log(array1.copyWithin(1, 3)); // expected output: Array [4, 4, 5, 4, 5]
数组的位置方法
1、indexOf() [Array.prototype.indexOf]=>MDN
方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。
arr.indexOf(searchElement)
arr.indexOf(searchElement[, fromIndex = 0])
2、lastIndexOf() [Array.prototype.lastIndexOf]=>MDN
lastIndexOf()
方法返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从 fromIndex
处开始。
arr.lastIndexOf(searchElement[, fromIndex = arr.length - 1])
var array = [2, 5, 9, 2]; var index = array.lastIndexOf(2); // index is 3 index = array.lastIndexOf(7); // index is -1 index = array.lastIndexOf(2, 3); // index is 3 index = array.lastIndexOf(2, 2); // index is 0 index = array.lastIndexOf(2, -2); // index is 0 index = array.lastIndexOf(2, -1); // index is 3
3、find() [Array.prototype.find]=>MDN
方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined
。
arr.find(callback[, thisArg])
find 方法对数组中的每一项元素执行一次 callback
函数,直至有一个 callback 返回 true
。当找到了这样一个元素后,该方法会立即返回这个元素的值,否则返回 undefined
。注意 callback
函数会为数组中的每个索引调用即从 0
到 length - 1
,而不仅仅是那些被赋值的索引,这意味着对于稀疏数组来说,该方法的效率要低于那些只遍历有值的索引的方法。
callback 函数带有3个参数:当前元素的值、当前元素的索引,以及数组本身。
如果提供了 thisArg 参数,那么它将作为每次 callback 函数执行时的上下文对象,否则上下文对象为 undefined
。
find 方法不会改变数组。
var inventory = [ {name: 'apples', quantity: 2}, {name: 'bananas', quantity: 0}, {name: 'cherries', quantity: 5} ]; function findCherries(fruit) { return fruit.name === 'cherries'; } console.log(inventory.find(findCherries)); // { name: 'cherries', quantity: 5 }
4、findIndex() [Array.prototype.findIndex]=>MDN
方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。
arr.findIndex(callback[, thisArg])
数组的迭代方法
1、every() [Array.prototype.every]=>MDN
every()
方法测试数组的所有元素是否都通过了指定函数的测试。
arr.every(callback[, thisArg])
every
方法为数组中的每个元素执行一次 callback
函数,直到它找到一个使 callback
返回 false(表示可转换为布尔值 false 的值)的元素。如果发现了一个这样的元素,every
方法将会立即返回 false
。否则,callback
为每一个元素返回 true
,every
就会返回 true
。callback
只会为那些已经被赋值的索引调用。不会为那些被删除或从来没被赋值的索引调用。
callback
被调用时传入三个参数:元素值,元素的索引,原数组。
如果为 every
提供一个 thisArg
参数,则该参数为调用 callback
时的 this
值。如果省略该参数,则 callback
被调用时的 this
值,在非严格模式下为全局对象,在严格模式下传入 undefined
。
every
不会改变原数组。
例子:检测所有数组元素的大小 下例检测数组中的所有元素是否都大于 10。 function isBigEnough(element, index, array) { return (element >= 10); } var passed = [12, 5, 8, 130, 44].every(isBigEnough); // passed is false passed = [12, 54, 18, 130, 44].every(isBigEnough); // passed is true
2、some() [Array.prototype.some]=>MDN
方法测试数组中的某些元素是否通过由提供的函数实现的测试。
arr.some(callback[, thisArg])
如果回调函数返回任何数组元素的truthy值,则返回true
;否则为false
。
some
为数组中的每一个元素执行一次 callback
函数,直到找到一个使得 callback 返回一个“真值”(即可转换为布尔值 true 的值)。如果找到了这样一个值,some
将会立即返回 true
。否则,some
返回 false
。callback
只会在那些”有值“的索引上被调用,不会在那些被删除或从来未被赋值的索引上调用。
var array = [1, 2, 3, 4, 5]; var even = function(element) { // checks whether an element is even return element % 2 === 0; }; console.log(array.some(even)); // expected output: true
3、filter() [Array.prototype.filter]=>MDN
filter()
方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。
var new_array = arr.filter(callback[, thisArg])
filter
为数组中的每个元素调用一次 callback
函数,并利用所有使得 callback
返回 true 或 等价于 true 的值 的元素创建一个新数组。callback
只会在已经赋值的索引上被调用,对于那些已经被删除或者从未被赋值的索引不会被调用。那些没有通过 callback
测试的元素会被跳过,不会被包含在新数组中。
callback
被调用时传入三个参数:
- 元素的值
- 元素的索引
- 被遍历的数组
filter
不会改变原数组,它返回过滤后的新数组。
4、forEach() [Array.prototypr.forEach]=>MDN
forEach()
方法对数组的每个元素执行一次提供的函数。
注意: 没有返回一个新数组! & 没有返回值!
应用场景:为一些相同的元素,绑定事件处理器!
array.forEach(callback(currentValue, index, array){ //do something }, this) array.forEach(callback[, thisArg])
参数
callback
- 为数组中每个元素执行的函数,该函数接收三个参数:
- currentValue(当前值)
- 数组中正在处理的当前元素。
- index(索引)
- 数组中正在处理的当前元素的索引。
- array
- forEach()方法正在操作的数组。
thisArg
可选- 可选参数。当执行回调 函数时
用作
this的
值(参考对象)。
返回值
undefined
.
function logArrayElements(element, index, array) { console.log("a[" + index + "] = " + element); } // 注意索引2被跳过了,因为在数组的这个位置没有项 [2, 5, ,9].forEach(logArrayElements); // a[0] = 2 // a[1] = 5 // a[3] = 9 [2, 5,"" ,9].forEach(logArrayElements); // a[0] = 2 // a[1] = 5 // a[2] = // a[3] = 9 [2, 5, undefined ,9].forEach(logArrayElements); // a[0] = 2 // a[1] = 5 // a[2] = undefined // a[3] = 9 let xxx; // undefined [2, 5, xxx ,9].forEach(logArrayElements); // a[0] = 2 // a[1] = 5 // a[2] = undefined // a[3] = 9
5、map() [Array.prototype.map]=>MDN
map()
方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
let new_array = arr.map(function callback(currentValue, index, array) {
// Return element for new_array
}[, thisArg])
// ES6 let numbers = [1, 5, 10, 15]; let doubles = numbers.map( x => x ** 2); // doubles is now [1, 25, 100, 225] // numbers is still [1, 5, 10, 15] const numbers = [2, 4, 8, 10]; let halves = numbers.map(x => x / 2); let numbers = [1, 4, 9]; let roots = numbers.map(Math.sqrt); // roots is now [1, 2, 3] // numbers is still [1, 4, 9]
map
方法会给原数组中的每个元素都按顺序调用一次 callback
函数。callback
每次执行后的返回值(包括 undefined
)组合起来形成一个新数组。 callback
函数只会在有值的索引上被调用;那些从来没被赋过值或者使用 delete
删除的索引则不会被调用。
一个坑:
["1", "2", "3"].map(parseInt); // 你可能觉的会是[1, 2, 3] // 但实际的结果是 [1, NaN, NaN] // 通常使用parseInt时,只需要传递一个参数. // 但实际上,parseInt可以有两个参数.第二个参数是进制数. // 可以通过语句"alert(parseInt.length)===2"来验证. // map方法在调用callback函数时,会给它传递三个参数:当前正在遍历的元素, // 元素索引, 原数组本身. // 第三个参数parseInt会忽视, 但第二个参数不会,也就是说, // parseInt把传过来的索引值当成进制数来使用.从而返回了NaN.
数组的归并方法
1、 reduce() [Array.prototypr.reduce]=>MDN
方法对累加器和数组中的每个元素(从左到右)应用一个函数,将其减少为单个值。
const array1 = [1, 2, 3, 4]; const reducer = (accumulator, currentValue) => accumulator + currentValue; // 1 + 2 + 3 + 4 console.log(array1.reduce(reducer)); // expected output: 10 // 5 + 1 + 2 + 3 + 4 console.log(array1.reduce(reducer, 5)); // expected output: 15
arr.reduce(callback[, initialValue])
参数
callback
- 执行数组中每个值的函数,包含四个参数:
accumulator
-
累加器累加回调的返回值; 它是上一次调用回调时返回的累积值,或
initialValue
(如下所示)。 currentValue
- 数组中正在处理的元素。
currentIndex
可选- 数组中正在处理的当前元素的索引。 如果提供了
initialValue
,则索引号为0,否则为索引为1。 array
可选- 调用
reduce
的数组
-
initialValue
可选- 用作第一个调用
callback
的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。
2、reduceRight() [Array.prototype.reduceRight]=>MDN
方法接受一个函数作为累加器(accumulator)和数组的每个值(从右到左)将其减少为单个值。
let flattened = [ [0, 1], [2, 3], [4, 5] ].reduceRight((a, b) => { return a.concat(b); }, []); // flattened is [4, 5, 2, 3, 0, 1]
参数
callback
- 一个回调函数,用来操作数组中的每个元素,可接受四个参数:
previousValue
- 上一次调用回调的返回值,或提供的
initialValue
currentValue
- 当前被处理的元素
index
- 当前处理元素的索引
array
- 调用
reduce
的数组
initialValue
- 可作为第一次调用回调
callback
的第一个参数