前言
数组作为在开发中罕用的汇合,除了for循环遍历以外,还有很多内置对象的办法,包含map,以及数组筛选元素filter等。
注:文章结尾处附深层次数组扁平化办法操作。
作为援用数据类型的一种,在解决数组Array的时候,咱们须要思考到深拷贝和浅拷贝的状况
能够参考以下文章
- javaScript中深拷贝和浅拷贝简略梳理
- 深度解析javaScript常见数据类型查看校验
罕用数组操作方法
push开端追加元素
/** * @param push 将一个或多个元素增加到数组的开端,返回该数组的新长度 * * 汇合apply和call合并数组 * */let user = ["zhangsan", "lisi"];console.log(user.push("xiaoming")); // 3console.log(user); // ["zhangsan", "lisi", "xiaoming"]let user1 = ["xiaowang", "xiaoming"];let user2 = ["zhangsan", "lisi"];console.log(Array.prototype.push.apply(user1, user2)); // 4console.log(user1); // ["xiaowang", "xiaoming", "zhangsan", "lisi"]
pop删除数组开端元素
/** * * @param pop 办法从数组中删除最初一个元素,返回值是该元素。 * * 如果数组是空数组,那么返回的是undefined * */let user = ["zhangsan", "lisi"];console.log(user.pop()); // lisiconsole.log(user); // ["zhangsan"]let empArray = [];console.log(empArray.pop()); // undefined
sort排序
/** * * @param sort * * 应用原地算法对数组的元素进行排序,并返回数组。 * 默认排序程序是在将元素转换为字符串,而后比拟它们的UTF-16代码单元值序列时构建的 * 因为它取决于具体实现,因而无奈保障排序的工夫和空间复杂性。 * * arr.sort([compareFunction]) * * @param compareFunction * * 用来指定按某种程序进行排列的函数。 * 如果省略,元素依照转换为的字符串的各个字符的Unicode位点进行排序。 * * 如果没有指明 compareFunction ,那么元素会依照转换为的字符串的诸个字符的Unicode位点进行排序。 * 例如 "Banana" 会被排列到 "cherry" 之前。 * 当数字按由小到大排序时,9 出 * 当初 80 之前,但因为(没有指明 compareFunction),比拟的数字会先被转换为字符串,所以在Unicode程序上 "80" 要比 "9" 要靠前。 * 如果指明了 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) 必须总是对雷同的输出返回雷同的比拟后果,否则排序的后果将是不确定的。 * * firstEl * 第一个用于比拟的元素。 * secondEl * 第二个用于比拟的元素 * *//** * * 根本用法 * * */const user = ["zhangsan", "lisi", "xiaoming", "xiaowang"];user.sort();console.log(user); // ["lisi", "xiaoming", "xiaowang", "zhangsan"]const array1 = [1, 30, 4, 21, 100000];array1.sort();console.log(array1); // [1, 100000, 21, 30, 4]/** * * 自定义排序办法 * * */var numbers = [4, 2, 5, 1, 3];let sortFun = function (a, b) { return a - b;};numbers.sort(sortFun);console.log(numbers); // [1, 2, 3, 4, 5]
shift数组结尾增加元素 && unshift数组结尾删除元素
/** * * @param shift * 从数组中删除第一个元素,并返回该元素的值,如果删除空数组,返回值是undefined * * @param unshift * 办法将一个或多个元素增加到数组的结尾,并返回该数组的新长度 * * */let user = ["zhangsan", "lisi"];console.log(user.shift()); // zhangsanconsole.log(user); // ["lisi"]let empArray = [];console.log(empArray.shift()); // undefinedlet user1 = ["xiaoming", "xiaowang"];console.log(user1.unshift("xiaoming1", "xiaowang1")); // 4console.log(user1); // ["xiaoming1", "xiaowang1", "xiaoming", "xiaowang"]
数组合并concat
/** * * @param concat * * 办法用于合并两个或多个数组。返回值是新数组,原数组不会产生更改 * * 注:数组合并是浅拷贝 * */let user = ["zhangsan", "lisi"];let user1 = [["xiaowang"], { name: "xiaoming" }];console.log(user.concat(user1)); // ["zhangsan","lisi",["xiaowang"],{name: "xiaoming"}]console.log(user); // ["zhangsan", "lisi"]
indexOf查找元素 && includes查找元素是否存在
/** * * @param indexOf * * 返回在数组中能够找到一个给定元素的第一个索引,如果不存在,则返回-1, * 罕用于判断数组是否存在某个元素 * * @param includes * * 判断一个数组是否蕴含一个指定的值,返回值是布尔值 true 或者 false * */let user = ["zhangsan", "lisi"];console.log(user.indexOf("lisi")); // 1console.log(user.indexOf("xiaoming")); // -1let user1 = ["zhangsan", ["xiaowang"], { name: "xiaoming" }];console.log(user1.includes("zhangsan")); // trueconsole.log(user1.includes(["xiaowang"])); // falseconsole.log(user1.includes({ name: "xiaoming" })); // false
reverse反转数组
/** * * @param reverse * * 反转数组元素,将原有数组顺叙显示,会扭转元素的元素地位 * */let user = ["zhangsan", "lisi", "xiaoming"];console.log(user.reverse()); // ["xiaoming", "lisi", "zhangsan"]console.log(user); // ["xiaoming", "lisi", "zhangsan"]let user1 = ["zhangsan", ["xiaowang", "lisi"], { name: "xiaoming" }];console.log(user1.reverse()); // [{name: "xiaoming"},["xiaowang", "lisi"],"zhangsan"]
数组切割成字符串join
/** * * @param join * * 依据传入的参数字符串,对数组进行切割,返回值是应用参数拼接元素的字符串 * 如果数组只有一个元素,则不应用宰割符号 * */let user = ["zhangsan", "lisi", "xiaoming"];console.log(user.join(" ")); // zhangsan lisi xiaomingconsole.log(user.join("")); // zhangsanlisixiaomingconsole.log(user.join(",")); // zhangsan,lisi,xiaomingconsole.log(user.join({ a: 1 })); // zhangsan[object Object]lisi[object Object]xiaomingconsole.log(user); // ["zhangsan", "lisi", "xiaoming"]
slice操作数组,替换,删除,新增
slice应用的范畴较广,不同的参数能够实现对数组的删除,新增和替换等,应用的时候须要留神参数的具体应用办法
/** * * @param slice * * 返回一个新的数组对象, * 这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包含 begin,不包含end)。原始数组不会被扭转。 * * @param begin * 提取起始处的索引(从 0 开始),从该索引开始提取原数组元素。 * 如果该参数为正数,则示意从原数组中的倒数第几个元素开始提取,slice(-2) 示意提取原数组中的倒数第二个元素到最初一个元素(蕴含最初一个元素)。 * 如果省略 begin,则 slice 从索引 0 开始。 * 如果 begin 超出原数组的索引范畴,则会返回空数组 * * @param end * * 提取终止处的索引(从 0 开始),在该索引处完结提取原数组元素。 * slice 会提取原数组中索引从 begin 到 end 的所有元素(蕴含 begin,但不蕴含 end)。 * slice(1,4) 会提取原数组中从第二个元素开始始终到第四个元素的所有元素 (索引为 1, 2, 3的元素)。 * 如果该参数为正数, 则它示意在原数组中的倒数第几个元素完结抽取。 * slice(-2,-1) 示意抽取了原数组中的倒数第二个元素到最初一个元素(不蕴含最初一个元素,也就是只有倒数第二个元素)。 * 如果 end 被省略,则 slice 会始终提取到原数组开端。如果 end 大于数组的长度,slice 也会始终提取到原数组开端。 * */const animals = ["ant", "bison", "camel", "duck", "elephant"];console.log(animals.slice(2)); // Array ["camel", "duck", "elephant"]console.log(animals.slice(2, 4)); // Array ["camel", "duck"]console.log(animals.slice(1, 5)); // Array ["bison", "camel", "duck", "elephant"]console.log(animals.slice(-2)); // Array ["duck", "elephant"]console.log(animals.slice(2, -1)); // Array ["camel", "duck"]console.log(animals.slice()); // Array ["ant", "bison", "camel", "duck", "elephant"]/** * * @param splice(start[, deleteCount[, item1[, item2[, ...]]]]) * * 通过删除或替换现有元素或者原地增加新的元素来批改数组,并以数组模式返回被批改的内容。此办法会扭转原数组 * * 由被删除的元素组成的一个数组。如果只删除了一个元素,则返回只蕴含一个元素的数组。如果没有删除元素,则返回空数组。 * * @param start * * 指定批改的开始地位,默认从下标0开始。 * 如果超出了数组的长度,则从数组开端开始增加元素; * 如果是负值,则示意从数组末位开始的第几位(从-1计数,这意味着-n是倒数第n个元素并且等价于array.length-n); * 如果正数的绝对值大于数组的长度,则示意开始地位为第0位。 * * @param deleteCount * * 整数,示意要移除的数组元素的个数。 * 如果 deleteCount 大于 start 之后的元素的总数,则从 start 前面的元素都将被删除(含第 start 位)。 * 如果 deleteCount 被省略了, * 或者它的值大于等于array.length - start(也就是说,如果它大于或者等于start之后的所有元素的数量), * 那么start之后数组的所有元素都会被删除。 * * 如果 deleteCount 是 0 或者正数,则不移除元素。这种状况下,至多应增加一个新元素。 * @param item1, item2, ... * * 要增加进数组的元素,从start 地位开始。如果不指定,则 splice() 将只删除数组元素 * */const months = ["Jan", "March", "April", "June"];months.splice(1, 0, "Feb"); // 下表为1,插入一个元素console.log(months); // ["Jan", "Feb", "March", "April", "June"]months.splice(4, 1, "May"); // 替换下标为4的元素console.log(months); // ["Jan", "Feb", "March", "April", "May"]let del = months.splice(1, 1); // 删除console.log(del); // ["Feb"]console.log(months); // ["Jan", "April", "May"]
every校验数组所有元素
/** * * @param every * 测试一个数组内的所有元素是否都能通过某个指定函数的测试,返回值是布尔值 true or false * 备注:若收到一个空数组,此办法在任何状况下都会返回 true。 * * arr.every(callback(element[, index[, array]])[, thisArg]) * callback * 用来测试每个元素的函数,它能够接管三个参数: * * @param element 用于测试的以后值。 * @param index可选 用于测试的以后值的索引。 * @param array可选 调用 every 的以后数组。 * * every 办法为数组中的每个元素执行一次 callback 函数,直到它找到一个会使 callback 返回 false 的元素。 * 如果发现了一个这样的元素,every 办法将会立刻返回 false。 * 否则,callback 为每一个元素返回 true,every 就会返回 true。 * * callback 只会为那些曾经被赋值的索引调用。不会为那些被删除或从未被赋值的索引调用。 * callback 在被调用时可传入三个参数:元素值,元素的索引,原数组。 * 如果为 every 提供一个 thisArg 参数,则该参数为调用 callback 时的 this 值。 * 如果省略该参数,则 callback 被调用时的 this 值,在非严格模式下为全局对象,在严格模式下传入 undefined。 * * * every 不会扭转原数组。 * every 遍历的元素范畴在第一次调用 callback 之前就已确定了。 * 在调用 every 之后增加到数组中的元素不会被 callback 拜访到。 * 如果数组中存在的元素被更改,则他们传入 callback 的值是 every 拜访到他们那一刻的值。 * 那些被删除的元素或从来未被赋值的元素将不会被拜访到。 * * */const isBelowThreshold = (currentValue) => currentValue < 40;const array1 = [1, 30, 39, 29, 10, 13];console.log(array1.every(isBelowThreshold)); // true
some 测试数组中是不是至多有1个元素通过了被提供的函数测试。返回值是布尔值
/** * * @param some 测试数组中是不是至多有1个元素通过了被提供的函数测试。返回值是布尔值 * * */const array = [1, 2, 3, 4, 5];const even = (element) => element % 2 === 0; //确认偶数console.log(array.some(even)); // true;
深层次递归数组flat
/** * @param flat 依照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。 * * var newArray = arr.flat([depth]) * @depth 指定要提取嵌套数组的构造深度,默认值为 1。 * */let arr1 = [1, 2, [3, 4]];console.log(arr1.flat()); // [1, 2, 3, 4]let arr2 = [1, 2, [3, 4, [5, 6]]];console.log(arr2.flat()); // [1, 2, 3, 4, [5, 6]]let arr3 = [1, 2, [3, 4, [5, 6]]];console.log(arr3.flat(2)); // [1, 2, 3, 4, 5, 6]//应用 Infinity,可开展任意深度的嵌套数组let arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];console.log(arr4.flat(Infinity)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]let objArray = [{ name: "zhangsan", children: ["张三"] }];console.log(objArray.flat(Infinity)); // [{ name: "zhangsan", children: ["张三"] }]
map遍历数组
/** * @param map * * 创立一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成 * * */const array1 = [1, 4, 9, 16];const map1 = array1.map((x) => x * 2);console.log(map1); // [2, 8, 18, 32]
reduce和filter
reduce和filter的基本操作办法在之前的文章有提到过,这里不做复述
文章地址:JavaScript 数组办法filter和reduce
数组操作示例:
数组对象依据属性整顿数组
/** * 依照数组对象某个属性整顿数据 * * */let user1 = [ { name: "zhangsan", age: 21 }, { name: "lisi", age: 20 }, { name: "xiaoming", age: 20 },];function groupBy(objectArray, property) { return objectArray.reduce(function (acc, obj) { let key = obj[property]; if (!acc[key]) { acc[key] = []; } acc[key].push(obj); return acc; }, {});}let ageList = groupBy(user1, "age");console.log(ageList); // {[{name: "lisi", age: 20},{name: "xiaoming", age: 20}],[{name: "zhangsan", age: 21}]}
数组扁平化-深层次
function flatten(array) { var flattend = []; (function flat(array) { array.forEach(function (el) { for (let i in el) { if (Object.prototype.toString.call(el[i]) === "[object Array]") flat(el[i]); } flattend.push(el); }); })(array); return flattend;}let user2 = [ { name: "zhangsan", age: 20, child: [{ name: "xiaoming" }], child1: [{ name: "xiaowang" }], },];let flattenArray = flatten(user2);console.log(flattenArray);
结尾
以上就是JavaScript中数组较为罕用的办法,其余没有提及的办法,须要的同学能够查阅相干文章,或者留言,后续的文章整顿而后作为补充。
源码地址
码云 https://gitee.com/lewyon/vue-note
githup https://github.com/akari16/vue-note
文章博客地址:JavaScript数组罕用办法解析和深层次js数组扁平化
欢送关注公众号:程序员布欧,不定期更新一些文章
创作不易,转载请注明出处和作者。