数组实例方法运用
数组有很多实例方法,有些方法不会更改现有数组,而是返回一个新数组,有些方法则会改变原数组。本篇文章所列方法全部摘自具体项目的真实案例。
1. forEach
对数组的每个元素执行一次给定的函数,不会改变原数组。
let obj = {a: 1, b: 2, c: 3};
Object.keys(obj).forEach((k) => (obj[k] = '1')); // 将一个对象的全部 value 变成 '1'
// {a: '1', b: '1', c: '1'}
2. push
将一个或多个元素添加到数组的末尾,并返回该数组的新长度。改变原数组。
const dates = ["2022-01-27 12:00:00", "2022-01-27 14:00:00"];
const xAxisData = [];
dates.forEach((item) => {
const date = item.split(' ').join('\n');
xAxisData.push(date);
});
// xAxisData: ['2022-01-27\n12:00:00', '2022-01-27\n14:00:00']
3. includes
判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false。不会改变原数组。
const category = ["制氧机", "血压计"];
category.includes("制氧机");
// true
4. map
创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。不会改变原数组。
const options = [{word: "老年人", score: 23}, {word: "中年人", score: 63}];
const data = options.map((item, index) => {return {...item, index: index + 1}});
// data: [{word: "老年人", score: 23, index: 1}, {word: "中年人", score: 63, index: 2}];
通常接口返回的数据需要调整(新增)某一个属性时,使用 map
非常合适。
当你不打算使用返回的新数组却使用
map
是违背设计初衷的,请用forEach
或者for-of
替代。
5. every
测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。不会改变原数组。
const data = [{name: '上传中', status: 1}, {name: '解析中', status: 2}, {name: '转换中', status: 3}, {name: '转换成功', status: 4}];
const completeStatus = data.every(item => item.status === 4);
if (completeStatus) {
console.log("状态已完成");
}
上例中,测试数组每一项元素的 status
属性是否等于 4,如果全部都是 4 ,则返回 true,表示完结状态。比如可以用于判断一个列表是否需要继续轮训。状态全部已完结就完全可以停止轮训。
6. filter
创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。 不会改变原数组。
// 某商品属性
const tags = ["机身质感", "产品款式", "机身大小", "机身重量", "移动方便性设计"];
const top3Tags = tags.filter((item, index) => index < 3);
// top3Tags: ["机身质感", "产品款式", "机身大小"]
上例中,只取数组前 3 项。
// 某商品属性,包含评价分数
const goods = [{name: "机身质感", score: 9}, {name:"产品款式", score: 11}, {name:"机身大小", score: 19}, {name:"机身重量", score: 5}, {name:"移动方便性设计", score: 44}];
const positiveGoods = goods.filter(item => item.score > 15);
// positiveGoods: [{name:"机身大小", score: 19}, {name:"移动方便性设计", score: 44}]
上例中,取数组元素 score 值大于 15 的项。
7. join
将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符。不会改变原数组。
// 部分互联网医疗上市企业
const brand = ["京东健康", "阿里将康", "平安好医生"];
const brandStr = barnd.join();
// brandStr: "京东健康,阿里将康,平安好医生"
8. sort
用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的。不会改变原数组。
const goods = [{name: "机身质感", score: 9}, {name:"产品款式", score: 11}, {name:"机身大小", score: 19}, {name:"机身重量", score: 5}, {name:"移动方便性设计", score: 44}];
const positiveGoods = goods.sort((a, b) => a.score - b.score); // 按照 score 从小到大排序(升序排序)
// positiveGoods: [{name:"机身重量", score: 5}, {name: "机身质感", score: 9}, {name:"产品款式", score: 11}, {name:"机身大小", score: 19}, {name:"移动方便性设计", score: 44}]
9. find
返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。不会改变原数组。
const options =
[
{
"label": "brand",
"name": "品牌",
"value": [
"鱼跃",
"欧姆龙",
"海尔",
"飞利浦"
]
},
{
"label": "message_source",
"name": "信息来源",
"value": [
"天猫评论",
"苏宁评论",
"京东评论"
]
}
];
const key = "message_source";
const obj = options.find((item) => item.label === key);
// obj: {
// "label": "message_source",
// "name": "信息来源",
// "value": [
// "天猫评论",
// "苏宁评论",
// "京东评论"
// ]
//}
以上例子,寻找 label
属性等于 message_source
的元素。
10. concat
用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。不会改变原数组。
let options = [];
// 求品牌交集
const a = new Set(["鱼跃", "欧姆龙", "可孚", "海尔", "乐普", "九安", "美菱"]);
const b = new Set(["乐普", "仁和", "可孚", "欧姆龙", "欧格斯", "氧精灵", "海尔"]);
const intersect = [...new Set([...a].filter((x) => b.has(x)))]; // ["欧姆龙", "可孚", "海尔", "乐普"]
intersect.forEach((elem) => {
options= options.concat([elem]);
});
// options: ['欧姆龙', '可孚', '海尔', '乐普']
11. reduce
对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。不会改变原数组。
// 将一个二维数组转变为一维数组
const arr = [["飞利浦", "海尔"], ["苏宁评论", "京东评论"]];
const arr2 = arr.reduce((a, b) => a.concat(b));
// arr2: ["飞利浦", "海尔", "苏宁评论", "京东评论"];
上例中,将一个二维数组转变为一维数组。
const x = [1, 2, 3, 4, 5, 6, 7];
const x2 = x.reduce((a, b) => a + b);
// x2: 28
上例中,求和。同理,一个很经典的问题:从 1 到 100 相加的和也可以这样求得!
计数,即查找数组中某一元素出现的次数或字符串中某一字符出现的次数,同样可以使用 reduce 来实现。
// 计数
const arr = [10, 20, 30, 40, 50, 10, 20, 30, 20];
const n = 20; // 查找20出现的个数
const count = arr.reduce((count, val) => {
return val === n ? count + 1 : count;
}, 0);
console.log("count", count);
上面代码中,reduce 方法第二个参数是 0,表示初始化时,count 是 0。然后遍历数组,碰到数组中某一元素和指定查找的值相同时,就将计数加 1。否则还是等于原计数的值。
字符串的计数可以先将字符串转化成数组在使用上面的方式,达到目标。
12. some
测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。不会改变原数组。
const data = [{name: '转换中', status: 3}, {name: '转换成功', status: 4}];
const uncompleteStatus = data.some(item => item.status === 3);
if (uncompleteStatus) {
console.log("状态未完成");
}
上例中,测试数组是否至少有一项元素的 status
属性等于 3,如果有 ,则返回 true,表示未完结状态。比如可以用于判断一个列表是否需要继续轮训。状态未完结就就需要轮训。