前言

数组作为在开发中常用的集合,除了for循环遍历以外,还有很多内置对象的方法,包括map,以及数组筛选元素filter等。

注:文章结尾处附深层次数组扁平化方法操作。

作为引用数据类型的一种,在处理数组Array的时候,我们需要考虑到深拷贝和浅拷贝的情况

可以参考以下文章

常用数组操作方法

push末尾追加元素

/**
* @param push 将一个或多个元素添加到数组的末尾,返回该数组的新长度
*
* 集合apply和call合并数组
*
*/
let user = ["zhangsan", "lisi"];
console.log(user.push("xiaoming")); // 3
console.log(user); // ["zhangsan", "lisi", "xiaoming"]
let user1 = ["xiaowang", "xiaoming"];
let user2 = ["zhangsan", "lisi"];
console.log(Array.prototype.push.apply(user1, user2)); // 4
console.log(user1); // ["xiaowang", "xiaoming", "zhangsan", "lisi"]

pop删除数组末尾元素

/**
*
* @param pop 方法从数组中删除最后一个元素,返回值是该元素。
*
* 如果数组是空数组,那么返回的是undefined
*
*/
let user = ["zhangsan", "lisi"];
console.log(user.pop()); // lisi
console.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()); // zhangsan
console.log(user); // ["lisi"]
let empArray = [];
console.log(empArray.shift()); // undefined
let user1 = ["xiaoming", "xiaowang"];
console.log(user1.unshift("xiaoming1", "xiaowang1")); // 4
console.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")); // 1
console.log(user.indexOf("xiaoming")); // -1
let user1 = ["zhangsan", ["xiaowang"], { name: "xiaoming" }];
console.log(user1.includes("zhangsan")); // true
console.log(user1.includes(["xiaowang"])); // false
console.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 xiaoming
console.log(user.join("")); // zhangsanlisixiaoming
console.log(user.join(",")); // zhangsan,lisi,xiaoming
console.log(user.join({ a: 1 })); // zhangsan[object Object]lisi[object Object]xiaoming
console.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中数组较为常用的方法,其他没有提及的方法,需要的同学可以查阅相关文章,或者留言,后续的文章整理然后作为补充。

源码地址

文章博客地址:JavaScript数组常用方法解析和深层次js数组扁平化

欢迎关注公众号:程序员布欧,不定期更新一些文章

创作不易,转载请注明出处和作者。

JavaScript数组常用方法解析和深层次js数组扁平化的更多相关文章

  1. javascript数组&省市联动分别用js数组和JSON实现

    1.定义数组的三种方式: **数组可以存放不同的数据类型   第一种: var arr=[1,2,3];   var arr=[1,"2",true];   第二种: 使用内置对象 ...

  2. JS将扁平化的数据处理成Tree结构

    let jsonData= [ { id:1,  parentId:0, name:"一级菜单A" }, { id:2, parentId:0, name:"一级菜单B& ...

  3. js数组的操作及数组与字符串的相互转化

    数组与字符串的相互转化 <script type="text/javascript">var obj="new1abcdefg".replace(/ ...

  4. .net中后台c#数组与前台js数组交互

    第一步:定义cs数组  cs文件里后台程序中要有数组,这个数组要定义成公共的数组.  public string[] lat = null;  public string[] lng = null; ...

  5. js数组学习整理

    原文地址:js数组学习整理 常用的js数组操作方法及原理 1.声明数组的方式 var colors = new Array();//空的数组 var colors = new Array(3); // ...

  6. php数组转换js数组操作及json_encode应用

    对于php,个人感觉能够熟练操作数组和字符串,基本上已经是入门了,php本身有很多操作数组和字符串的函数,今天在做一个功能时,需要用Js动态的创建门店信息,这些信息是要从后台添加的,想来想去,通过ph ...

  7. [jQ/PHP]再谈使用JS数组储值的运用(提交PHP处理)

    --------------------------------------------------------------------------------------------------- ...

  8. 前端开发:Javascript中的数组,常用方法解析

    前端开发:Javascript中的数组,常用方法解析 前言 Array是Javascript构成的一个重要的部分,它可以用来存储字符串.对象.函数.Number,它是非常强大的.因此深入了解Array ...

  9. javascript数组详解(js数组深度解析)【forEach(),every(),map(),filter(),reduce()】

    Array 对象是一个复合类型,用于在单个的变量中存储多个值,每个值类型可以不同. 创建数组对象的方法: new Array(); new Array(size); new Array(element ...

随机推荐

  1. java支持多继承吗

    java不支持多继承,只支持单继承(即一个类只能有一个父类).但是java接口支持多继承,即一个子接口可以有多个父接口.(接口的作用是用来扩展对象的功能,一个子接口继承多个父接口,说明子接口扩展了多个 ...

  2. C语言之数据类型(知识点8)

    一.数据类型 1.数据基本类型 (1)整数 ①有符号整形 有符号短整型 short 有符号基本整形  int 有符号长整形  long ②无符号整形 无符号基本整形 无符号短整型 无符号长整型 (2) ...

  3. Pandas数据统计函数

    Pandas数据统计函数 汇总类统计 唯一去重和按值计数 相关系数和协方差 0.读取csv数据 1.汇总类统计 2.唯一去重和按值计数 2.1 唯一性去重 一般不用于数值列,而是枚举.分类列 2.2 ...

  4. 实现拖拽复制和可排序的react.js组件

    在实现复制前,对之前的拖拽排序组件属性进行了修改. 摒弃了value中的content属性,拖拽组件暴露的render函数,利用这个属性进行组件内部子组件的渲染,这点主要是参考了蚂蚁金服的Ant de ...

  5. 【vue 开发】Vue中splice的使用

    splice(index,len,[item])它也可以用来替换/删除/添加数组内某一个或者几个值(该方法会改变原始数组) index:数组开始下标 len: 替换/删除的长度 item:替换的值,删 ...

  6. web.xml 配置 contextConfigLocation

    web.xml中classpath:和classpath*:  有什么区别? classpath:只会到你的class路径中查找找文件; classpath*:不仅包含class路径,还包括jar文件 ...

  7. smdms超市订单管理系统之登录功能

    一.超市订单管理系统准备阶段 Supermarket order management system 创建数据库 数据库代码放置如下 点击查看数据库address代码 CREATE TABLE `sm ...

  8. Python学习进度汇报

    学习进度还是比较慢的,上周五(18号晚上安装了Pycharm)就开始学,五天只到这个位置,当前一直是2倍速看黑马的Python视频,外加查看菜鸟的文档,需要加快一些进度了,后续还有后续的目标要实现,争 ...

  9. OpenHarmony 3.1 Beta 版本关键特性解析——ArkUI canvas组件

    (以下内容来自开发者分享,不代表 OpenHarmony 项目群工作委员会观点) 江英杰 华为技术有限公司 canvas 是 ArkUI 开发框架里的画布组件,常用于自定义绘制图形.因为其轻量.灵活. ...

  10. vue 组件复用 - component

    vue 组件复用 - component vue 组件复用 就是对 component 标签的使用 先看图 下图看使用 结果: 可以看到 在箱包 这一项,我将banner 组件用了两次,我 每次 点击 ...