数组对象常用方法"/>
web 数组对象常用方法
目录
前言
数组对象-Array
创建数组
判断是否为数组类型
根据元素找索引
Array.prototype.indexOf()
Array.prototype.lastIndexOf()
添加数组元素
Array.prototype.push()
Array.prototype.unshift()
删除数组元素
Array.prototype.pop()
Array.prototype.shift()
合并数组
Array.prototype.concat()
修改数组元素
Array.prototype.splice()
语法splice()
示例
截取数组元素
Array.prototype.slice()
数组元素排序
Array.prototype.reverse()
Array.prototype.sort()
数组转换成字符串
Array.prototype.join()
Array.prototype.toString()
总结
前言
该文章所有代码均在标签<script></script>下。
数组对象-Array
参考于MDN
在 JavaScript 中,数组不是基本类型,而是具有以下核心特征的 Array
对象:
-
JavaScript 数组是可调整大小的,并且可以包含不同的数据类型。(当不需要这些特征时,可以使用类型化数组)
-
JavaScript 数组不是关联数组,因此,不能使用任意字符串作为索引访问数组元素,但必须使用非负整数(或它们各自的字符串形式)作为索引访问。
-
JavaScript 数组的索引从 0 开始:数组的第一个元素在索引
0
处,第二个在索引1
处,以此类推,最后一个元素是数组的 length 属性减去1
的值。 -
JavaScript 数组复制操作创建浅拷贝。(所有 JavaScript 对象的标准内置复制操作都会创建浅拷贝,而不是深拷贝)。
创建数组
// 1.字面量方式创建const arr = [5,"food",false,[1,2,3],{name:"小宁"}];console.log(arr);// 2. Array() 构造函数 方式创建const arr2 = new Array(2);console.log(arr2.length); // 2console.log(arr2[0]); // undefinedlet fruits = new Array('Apple', 'Banana');console.log(fruits.length); // 2console.log(fruits[0]); // Apple// 3.String.prototype.split() 创建数组const fruits2 = 'Apple, Banana'.split(',');console.log(fruits2.length); // 2console.log(fruits2[0]); // Apple
判断是否为数组类型
-
Array.isArray()
如果参数是数组则返回
true
,否则返回false
。 -
instanceof
运算符instanceof
运算符用来检测构造函数的prototype
属性(constructor.prototype
) 是否存在于参数object
的原型链上。
const arr = [5,"food",false,[1,2,3],{name:"小宁"}];const obj = {name:"Tom"}console.log(Array.isArray(arr)); // true console.log(Array.isArray(obj)); // falseconsole.log(arr instanceof Array);// trueconsole.log(obj instanceof Array);// false
根据元素找索引
-
Array.prototype.indexOf()
indexOf()
方法返回在数组中可以找到给定元素的第一个索引,如果不存在,则返回 -1。 -
Array.prototype.lastIndexOf()
lastIndexOf()
方法返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从fromIndex
处开始。
Array.prototype.indexOf()
参考于: Array.prototype.indexOf() - JavaScript | MDN (mozilla)
语法indexOf()
indexOf(searchElement)indexOf(searchElement, fromIndex)
参数:
-
searchElement
要查找的元素。
-
fromIndex
可选开始查找的位置。如果该索引值大于或等于数组长度,意味着不会在数组里查找,返回 -1。如果参数中提供的索引值是一个负值,则将其作为数组末尾的一个抵消,即 -1 表示从最后一个元素开始查找,-2 表示从倒数第二个元素开始查找,以此类推。注意:如果参数中提供的索引值是一个负值,并不改变其查找顺序,查找顺序仍然是从前向后查询数组。如果抵消后的索引值仍小于 0,则整个数组都将会被查询。其默认值为 0。
返回值
首个被找到的元素在数组中的索引位置; 若没有找到则返回 -1。
const beasts = ['a','b','c','d',1,2,3];console.log(beasts.indexOf("d"));console.log(beasts.indexOf(4));console.log(beasts.indexOf("d",2));console.log(beasts.indexOf(2,-1));console.log(beasts.indexOf(2,-2));
该程序输出结果如下图所示:
示例
找出指定元素出现的所有位置
// 找出指定元素出现的所有位置const indices = [];const array = ['a', 'b', 'a', 'c', 'a', 'd'];const element = 'a';let idx = array.indexOf(element);while (idx !== -1) {indices.push(idx);idx = array.indexOf(element, idx + 1);}console.log(indices);// [0, 2, 4]
判断一个元素是否在数组里,不在则更新数组
// 判断一个元素是否在数组里,不在则更新数组const array = ['potato', 'tomato', 'chillies', 'green-pepper'];function updateArrayCollection (params) {if(array.indexOf(params) === -1){array.push(params)console.log("已添加数据:" + params);}else{console.log("数组中已存在该数据:" + params);}}updateArrayCollection("foods")// 已添加数据:foodsupdateArrayCollection("foods")// 数组中已存在该数据:foodsconsole.log(array);
Array.prototype.lastIndexOf()
参考于:Array.prototype.lastIndexOf() - JavaScript | MDN (mozilla)
该方法与indexOf()
方法的用法基本一样,需要注意一下:
-
参数:
fromIndex
可选 与indexOf()
不同从此位置开始逆向查找。默认为数组的长度减 1(
arr.length - 1
),即整个数组都被查找。如果该值大于或等于数组的长度,则整个数组会被查找。如果为负值,将其视为从数组末尾向前的偏移。即使该值为负,数组仍然会被从后向前查找。如果该值为负时,其绝对值大于数组长度,则方法返回 -1,即数组不会被查找。 -
使用该方法查找元素位置时,
var indices = [];var array = ['a', 'b', 'a', 'c', 'a', 'd'];var element = 'a';var idx = array.lastIndexOf(element);while (idx != -1) {indices.push(idx);idx = (idx > 0 ? array.lastIndexOf(element, idx - 1) : -1);}console.log(indices);// [4, 2, 0];
注意:我们要单独处理
idx==0
时的情况,因为如果是第一个元素,忽略了fromIndex
参数则第一个元素总会被查找。这不同于indexOf方法注:原英文是针对使用三元操作符语句的作用进行说明的:
idx = (idx > 0 ? array.lastIndexOf(element, idx - 1) : -1);
idx > 0
时,才进入 lastIndexOf 由后往前移一位进行倒查找;如果idx == 0
则直接设置idx = -1
,循环while (idx != -1)
就结束了。
添加数组元素
-
Array.prototype.push()
push()
方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度。push(element0, element1, /* … ,*/ elementN)
-
Array.prototype.unshift()
unshift()
方法将一个或多个元素添加到数组的开头,并返回该数组的新长度。unshift(element0, element1, /* … ,*/ elementN)
Array.prototype.push()
const arr = ["A","B","C"]console.log(arr.push('D','F')); // 5console.log(arr);
Array.prototype.unshift()
const arr = ["A","B","C"]console.log(arr.unshift(0,1));// 5console.log(arr);
删除数组元素
-
Array.prototype.pop()
pop()
方法从数组中删除最后一个元素,并返回该元素的值。此方法会更改数组的长度。 -
Array.prototype.shift()
shift()
方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。
Array.prototype.pop()
const arr = ["A","B","C","D","E","F"]console.log(arr.pop()); // Fconsole.log(arr);
Array.prototype.shift()
const arr = ["A","B","C","D","E","F"]console.log(arr.shift()); // Aconsole.log(arr);
合并数组
Array.prototype.concat()
参考于:Array.prototype.concat() - JavaScript | MDN (mozilla)
语法
concat()concat(value0)concat(value0, value1)concat(value0, value1, /* … ,*/ valueN)
参数
valueN
可选
数组和/或值,将被合并到一个新的数组中。如果省略了所有 valueN
参数,则 concat
会返回调用此方法的现存数组的一个浅拷贝。
返回值
新的 Array 实例。
描述
concat
方法创建一个新的数组,它由被调用的对象中的元素组成,每个参数的顺序依次是该参数的元素(如果参数是数组)或参数本身(如果参数不是数组)。它不会递归到嵌套数组参数中。
concat
方法不会改变 this
或任何作为参数提供的数组,而是返回一个浅拷贝,它包含与原始数组相结合的相同元素的副本。原始数组的元素将复制到新数组中,如下所示:
-
对象引用(而不是实际对象):
concat
将对象引用复制到新数组中。原始数组和新数组都引用相同的对象。也就是说,如果引用的对象被修改,则更改对于新数组和原始数组都是可见的。这包括也是数组的数组参数的元素。 -
数据类型如字符串,数字和布尔(不是 String,Number 和 Boolean 对象):
concat
将字符串和数字的值复制到新数组中。
备注: 数组/值在连接时保持不变。此外,对于新数组的任何操作(仅当元素不是对象引用时)都不会对原始数组产生影响,反之亦然。
const letters = ['a','b','c'];const numbers = [1,2,3];const symbols = ['*','@','%'];const mergeArr = letters.concat(letters,numbers,symbols);console.log(mergeArr);
此程序输出结果如下图所示为:
修改数组元素
Array.prototype.splice()
参考于:Array.prototype.splice() - JavaScript | MDN (mozilla)
splice()
方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。
语法splice()
splice(start)splice(start, deleteCount)splice(start, deleteCount, item1)splice(start, deleteCount, item1, item2, itemN)
参数
-
start
指定修改的开始位置(从 0 计数)。如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位(从 -1 计数,这意味着 -n 是倒数第 n 个元素并且等价于
array.length-n
);如果负数的绝对值大于数组的长度,则表示开始位置为第 0 位。 -
deleteCount
可选整数,表示要移除的数组元素的个数。如果
deleteCount
大于start
之后的元素的总数,则从start
后面的元素都将被删除(含第start
位)。如果deleteCount
被省略了,或者它的值大于等于array.length - start
(也就是说,如果它大于或者等于start
之后的所有元素的数量),那么start
之后数组的所有元素都会被删除。如果deleteCount
是 0 或者负数,则不移除元素。这种情况下,至少应添加一个新元素。 -
item1, item2, ...
可选要添加进数组的元素,从
start
位置开始。如果不指定,则splice()
将只删除数组元素。
返回值
由被删除的元素组成的一个数组。如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组。
描述
如果添加进数组的元素个数不等于被删除的元素个数,数组的长度会发生相应的改变
示例
从索引 2 的位置开始删除 0 个元素,插入"drum"
var myFish = ["angel", "clown", "mandarin", "sturgeon"];var removed = myFish.splice(2, 0, "drum");// 运算后的 myFish: ["angel", "clown", "drum", "mandarin", "sturgeon"]// 被删除的元素:[], 没有元素被删除
从索引 2 的位置开始删除 0 个元素,插入“drum”和 "guitar"
var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];var removed = myFish.splice(2, 0, 'drum', 'guitar');// 运算后的 myFish: ["angel", "clown", "drum", "guitar", "mandarin", "sturgeon"]// 被删除的元素:[], 没有元素被删除
从索引 3 的位置开始删除 1 个元素
var myFish = ['angel', 'clown', 'drum', 'mandarin', 'sturgeon'];var removed = myFish.splice(3, 1);// 运算后的 myFish: ["angel", "clown", "drum", "sturgeon"]// 被删除的元素:["mandarin"]
从索引 2 的位置开始删除 1 个元素,插入“trumpet”
var myFish = ['angel', 'clown', 'drum', 'sturgeon'];var removed = myFish.splice(2, 1, "trumpet");// 运算后的 myFish: ["angel", "clown", "trumpet", "sturgeon"]// 被删除的元素:["drum"]
从索引 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"]
从索引 2 的位置开始删除 2 个元素
var myFish = ['parrot', 'anemone', 'blue', 'trumpet', 'sturgeon'];var removed = myFish.splice(myFish.length - 3, 2);// 运算后的 myFish: ["parrot", "anemone", "sturgeon"]// 被删除的元素:["blue", "trumpet"]
从索引 -2 的位置开始删除 1 个元素
var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];var removed = myFish.splice(-2, 1);// 运算后的 myFish: ["angel", "clown", "sturgeon"]// 被删除的元素:["mandarin"]
从索引 2 的位置开始删除所有元素
var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];var removed = myFish.splice(2);// 运算后的 myFish: ["angel", "clown"]// 被删除的元素:["mandarin", "sturgeon"]
截取数组元素
Array.prototype.slice()
参考于:Array.prototype.slice() - JavaScript | MDN (mozilla)
slice()
方法返回一个新的数组对象,这一对象是一个由 begin
和 end
决定的原数组的浅拷贝(包括 begin
,不包括end
)。原始数组不会被改变。
语法
slice()slice(start)slice(start,end)
参数
-
begin
可选提取起始处的索引(从
0
开始),从该索引开始提取原数组元素。如果该参数为负数,则表示从原数组中的倒数第几个元素开始提取,slice(-2)
表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素)。如果省略begin
,则slice
从索引0
开始。如果begin
超出原数组的索引范围,则会返回空数组。 -
end
可选提取终止处的索引(从
0
开始),在该索引处结束提取原数组元素。slice
会提取原数组中索引从begin
到end
的所有元素(包含begin
,但不包含end
)。slice(1,4)
会提取原数组中从第二个元素开始一直到第四个元素的所有元素(索引为 1, 2, 3 的元素)。如果该参数为负数,则它表示在原数组中的倒数第几个元素结束抽取。slice(-2,-1)
表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)。如果end
被省略,则slice
会一直提取到原数组末尾。如果end
大于数组的长度,slice
也会一直提取到原数组末尾。
返回值
一个含有被提取元素的新数组。
描述
slice
不会修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。原数组的元素会按照下述规则拷贝:
-
如果该元素是个对象引用(不是实际的对象),
slice
会拷贝这个对象引用到新的数组里。两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变。 -
对于字符串、数字及布尔值来说(不是 String、Number 或者 Boolean 对象),
slice
会拷贝这些值到新的数组里。在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组。
如果向两个数组任一中添加了新元素,则另一个不会受到影响。
const arr = ['a','b','c',1,2,3];console.log(arr.slice(1,3)); // ['b', 'c']
数组元素排序
-
Array.prototype.reverse()
reverse()
方法将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。该方法会改变原数组。 -
Array.prototype.sort()
sort()
方法用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的 UTF-16 代码单元值序列时构建的由于它取决于具体实现,因此无法保证排序的时间和空间复杂性。
Array.prototype.reverse()
const array = ['one', 'two', 'three'];console.log(array);// expected output: Array ["one", "two", "three"]console.log(array.reverse());// expected output: Array ["three", "two", "one"]
Array.prototype.sort()
参考于: Array.prototype.sort() - JavaScript | MDN (mozilla)
sort()
语法
// 无函数sort()// 箭头函数sort((a, b) => { /* … */ } )// 比较函数sort(compareFn)// 内联比较函数sort(function compareFn(a, b) { /* … */ })
-
参数
compareFn
可选用来指定按某种顺序进行排列的函数。如果省略,元素按照转换为的字符串的各个字符的 Unicode 位点进行排序。
-
a
:第一个用于比较的元素。 -
b
:第二个用于比较的元素。
-
-
返回值
排序后的数组。请注意,数组已原地排序,并且不进行复制。
描述
如果没有指明 compareFn
,那么元素会按照转换为的字符串的诸个字符的 Unicode 位点进行排序。例如 "Banana" 会被排列到 "cherry" 之前。当数字按由小到大排序时,9 出现在 80 之前,但因为(没有指明 compareFn
),比较的数字会先被转换为字符串,所以在 Unicode 顺序上 "80" 要比 "9" 要靠前。
如果指明了 compareFn
,那么数组会按照调用该函数的返回值排序。即 a 和 b 是两个将要被比较的元素:
-
如果
compareFn(a, b)
大于 0,b 会被排列到 a 之前。 -
如果
compareFn(a, b)
小于 0,那么 a 会被排列到 b 之前; -
如果
compareFn(a, b)
等于 0,a 和 b 的相对位置不变。备注:ECMAScript 标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如 Mozilla 在 2003 年之前的版本); -
compareFn(a, b)
必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。
compareFn(a, b) 返回值 | 排序顺序 |
---|---|
> 0 | a 在 b 后 |
< 0 | a 在 b 前 |
=== 0 | 保持 a 和 b 的顺序 |
所以,比较函数格式如下:
function compareFn(a, b) {if (在某些排序规则中,a 小于 b) {return -1;}if (在这一排序规则下,a 大于 b) {return 1;}// a 一定等于 breturn 0;}
要比较数字而非字符串,比较函数可以简单的用 a
减 b
,如下的函数将会将数组升序排列(如果它不包含 Infinity
和 NaN
):
function compareNumbers(a, b) {return a - b;}
sort
方法可以使用 函数表达式 方便地书写:
const numbers = [4, 2, 5, 1, 3];numbers.sort(function (a, b) {return a - b;});console.log(numbers);// [1, 2, 3, 4, 5]// 或者const numbers2 = [4, 2, 5, 1, 3];numbers2.sort((a, b) => a - b);console.log(numbers2);// [1, 2, 3, 4, 5]
对象可以按照某个属性排序:
const items = [{ name: 'Edward', value: 21 },{ name: 'Sharpe', value: 37 },{ name: 'And', value: 45 },{ name: 'The', value: -12 },{ name: 'Magnetic', value: 13 },{ name: 'Zeros', value: 37 }];// sort by valueitems.sort((a, b) => a.value - b.value);// sort by nameitems.sort((a, b) => {const nameA = a.name.toUpperCase(); // ignore upper and lowercase 忽略大小写const nameB = b.name.toUpperCase(); // ignore upper and lowercaseif (nameA < nameB) {return -1;}if (nameA > nameB) {return 1;}// names must be equal 名称必须相等return 0;});
一个与底层相关的小的注意的点:
const numArr = [5,9,1,7,50,90,100,30,80,2840]console.log(numArr.sort(compareNumbers)); // 这里 compareNumbers 后面不能加小括号,会出错function compareNumbers(a,b) {if(a > b){return -1;}else if(a < b){return 1;}return 0;}
对非 ASCII 字符排序
当排序非 ASCII 字符的字符串(如包含类似 e, é, è, a, ä 等字符的字符串)。一些非英语语言的字符串需要使用 String.localeCompare。这个函数可以将函数排序到正确的顺序。
var items = ['réservé', 'premier', 'cliché', 'communiqué', 'café', 'adieu'];items.sort(function (a, b) {return a.localeCompare(b);});// items is ['adieu', 'café', 'cliché', 'communiqué', 'premier', 'réservé']
使用映射改善排序
compareFunction
可能需要对元素做多次映射以实现排序,尤其当 compareFunction
较为复杂,且元素较多的时候,某些 compareFunction
可能会导致很高的负载。使用 map 辅助排序将会是一个好主意。基本思想是首先将数组中的每个元素比较的实际值取出来,排序后再将数组恢复。
// 需要被排序的数组var list = ['Delta', 'alpha', 'CHARLIE', 'bravo'];// 对需要排序的数字和位置的临时存储var mapped = list.map(function(el, i) {return { index: i, value: el.toLowerCase() };})// 按照多个值排序数组mapped.sort(function(a, b) {return +(a.value > b.value) || +(a.value === b.value) - 1;});// 根据索引得到排序的结果var result = mapped.map(function(el){return list[el.index];});
数组转换成字符串
-
Array.prototype.join()
join()
方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串,用逗号或指定的分隔符字符串分隔。如果数组只有一个元素,那么将返回该元素而不使用分隔符。 -
Array.prototype.toString()
toString()
方法返回一个字符串,表示指定的数组及其元素。
Array.prototype.join()
将数组的所有元素连接为字符串。
// 从数组中创建一个字符串const elements = ['Fire', 'Air', 'Water'];console.log(elements.join()); // Fire,Air,Waterconsole.log(elements.join(", ")); // Fire, Air, Water console.log(elements.join('')); // FireAirWaterconsole.log(elements.join('-')); // Fire-Air-Water// 在稀疏数组上使用 join()// join() 将空槽视为 undefined,并产生额外的分隔符:console.log([1, , 3].join()); // '1,,3'console.log([1, undefined, 3].join()); // '1,,3'
Array.prototype.toString()
参考于:Array.prototype.toString() - JavaScript | MDN (mozilla)
Array 对象覆盖了 Object 的 toString
方法。对于数组对象,toString
方法在内部调用 join() 方法拼接数组中的元素并返回一个字符串,其中包含用逗号分隔的每个数组元素。如果 join
方法不可用,或者它不是一个函数,将使用 Object.prototype.toString 代替,返回 [object Array]
。
const arr = [];arr.join = 1; // re-assign `join` with a non-function 用非函数重新分配' join 'console.log(arr.toString()); // Logs [object Array] console.log(Array.prototype.toString.call({ join: () => 1 })); // Logs 1
当一个数组被作为文本值或者进行字符串拼接操作时,将会自动调用其 toString
方法。
const array1 = [1, 2, 'a', '1a'];console.log(array1.toString());// expected output: "1,2,a,1a"
总结
该文章大量参考MDN数组对象部分。仅仅是我自学的一个笔记,我还有一部分没有看懂。
我的笔记都在这里gitee学习笔记.git
这里只是记录的部分常用数组对象方法,详情请参考MND
更多推荐
web 数组对象常用方法
发布评论