js如何优化这个数组遍历取值的方法

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 的答案。不过提醒一句,并不是代码简单就算优化,基于可读性优化还是要容易看明白才好;而基于性能优化,那就需要执行效率高。


再补充一下,有几个容错/优化点要注意:

  1. 注意处理按 type 找不到 bottle 的情况
  2. 确保 bottle 下有 process;优化的情况下可以再判断是空数组直接返回 []
  3. includes 对少量 id 可用,如果量大,建议用 Set
  4. 注意 process id 和 id 列表中的 id 类型是否一致(同为字符串),如果不一致最好先处理成一致。
  5. 对于函数 filterBottleProcess 来说,idList 应该有校验(判断是否空)的操作,并且对空 idList 进行适当的逻辑处理(是返回 [] 还是返回所有?)


回答:

water.find(v => v.bottleType === bottleType)?.process?.filter(v => id.includes(v.id))

以上是 js如何优化这个数组遍历取值的方法 的全部内容, 来源链接: utcz.com/p/937412.html

回到顶部