js如何优化这个数组遍历取值的方法
给定一个数组大致如下
water = [{ bottleType: "DO", //溶解氧
process: [{
name: "标定记录",
component: "",
id: "1"
},
{
name: "分析结果",
component: "",
id: "2"
},
{
name: "使用记录",
component: "",
id: "3"
}
]
},
{
bottleType: "P", //Ph
process: [{
name: "标定记录",
component: "",
id: "1"
},
{
name: "分析结果",
component: "",
id: "2"
},
{
name: "使用记录",
component: "",
id: "3"
}
]
},
{
bottleType: "ALK", //总碱度
process: [{
name: "标定记录",
component: "",
id: "1"
},
{
name: "分析结果",
component: "",
id: "2"
},
{
name: "使用记录",
component: "",
id: "3"
}
]
},
{
bottleType: "N", //营养盐
process: [{
name: "试剂配置",
component: "",
id: "4"
},
{
name: "标准溶液稀释",
component: "",
id: "5"
},
{
name: "标准曲线",
component: "",
id: "6"
},
{
name: "分析结果",
component: "",
id: "2"
},
{
name: "使用记录",
component: "",
id: "3"
}
]
},
{
bottleType: "X", //悬浮物
process: [{
name: "称量记录",
component: "",
id: "7"
},
{
name: "分析结果",
component: "",
id: "2"
},
{
name: "使用记录",
component: "",
id: "3"
}
]
},
];
接口返回两个字段例如
bottleType:"xx",id:["1","4"]
要求拿这两个字段 从water这个数组里面返回对应bottleType下的匹配process集合
比如返回的bottleType = "N" id集合是 5,6
就返回营养盐下的 标准溶液稀释 跟 标准曲线 组成新的数组
目前的方法是用一次find 然后再嵌套两次forEach 觉得很麻烦 想知道有没有更简洁的方法
回答:
要在一组数据里找某个数据,最基本的程序,就是循环对比。学任何语言的第二章左右,程序结构的时候都会讲到的分支和循环结构。(当然题主问的是优化,先把最基本的写出来,再优化)
const bottleType = "N";let found = false;
for (let i = 0; i < water.length; i++) {
if (water[i].bottleType === bottleType) {
// TODO 这里找到了,近一步处理
found = true;
break;
// 这里做个标记,然后 break
// 或者在函数里直接 return
}
}
// 遍历完都没找到,那就是没得
// 注意这里检查标记
这里的 found
标记,也可以用对象引用来代替,比如初始 found = null
,如果找到,found = water[i]
。循环结束之后判断 found
是否非空就行。
找到单瓶之后,再按 ID 进行过滤,这是一个典型的双层循环结构
let foundBottle = ... // 假设找到了 bottle 数据引用在这里const result = []; // 准备一个空数组用来保存找到的 process
// 第一层遍历 process,记得做必要的判断:是否存在 process,或者更进一步判断是否空数组
for (let j = 0; j < foundBottle.process.length; j++) {
// 第二层遍历给的 idList,挨个判断
for (let k = 0; k < idList.length; k++) {
if (foundBottle.process[j].id === idList[k]) {
// 找到了,存起来
result.push(foundBottle.process[j]);
}
}
}
好了,这是采用最基本的程序结构来完成的。但 JS 和各种库提供了方便的工具,比如查找,可以用 Array
提供的 find
方法,那么第一个循环可以改为一句话:
const foundBottle = water.find(it => it.bottleType === bottleType);
后面的双层循环中,内循环可以用数组提供的 includes
来代替
if (idList.includes(foundBottle.process[j].id)) { result.push(...);
}
外循环可以用数组的 filter
来代替,合并上面的条件,就是
foundBottle.process.filter(p => idList.includes(p.id))
完整的函数可以写成
function filterBottleProcess(data, bottleType, idList) { const bottle = data.find(({ bottleType: type }) => type === bottleType);
if (bottle) {
return bottle.process.filter(({ id }) => idList.includes(id));
} else {
return [];
}
}
如果再利用可选链运算符和空值合并运算符等,就会得到 @zangeci 的答案。不过提醒一句,并不是代码简单就算优化,基于可读性优化还是要容易看明白才好;而基于性能优化,那就需要执行效率高。
再补充一下,有几个容错/优化点要注意:
- 注意处理按 type 找不到 bottle 的情况
- 确保 bottle 下有 process;优化的情况下可以再判断是空数组直接返回
[]
includes
对少量 id 可用,如果量大,建议用Set
- 注意 process id 和 id 列表中的 id 类型是否一致(同为字符串),如果不一致最好先处理成一致。
- 对于函数
filterBottleProcess
来说,idList
应该有校验(判断是否空)的操作,并且对空 idList 进行适当的逻辑处理(是返回[]
还是返回所有?)
回答:
water.find(v => v.bottleType === bottleType)?.process?.filter(v => id.includes(v.id))
以上是 js如何优化这个数组遍历取值的方法 的全部内容, 来源链接: utcz.com/p/937412.html