javascript - 使用 map reduce 等,您将如何在嵌套数组中找到符合特定条件的第一项,并在找到后停止?
问题描述
您如何在嵌套数组中找到符合特定条件的第一项,并在找到后停止?
在 1D 数组中,这就是 Array.find 函数的用途,但是对于 2D 数组,甚至更简洁的 n 维数组,您将如何做呢?
此外,我正在尝试使用 es6 和数组函数(例如 find、map、reduce 等)提出一个简洁的解决方案,而不是使用更传统的循环和变量来维护状态(请参阅下面的一个这样的老式解决方案)。
数据可能看起来像这样
const data = [
{arr: [{val:6,name:'aaa'},{val:4,name:'bbb'},{val:8,name:'ccc'}]},
{arr: [{val:3,name:'mmm'},{val:5,name:'nnn'},{val:9,name:'ppp'},{val:5,name:'ooo'}]}
]
我希望我可以做一些类似于array.find(及其谓词/测试功能)的事情,但我需要更深入地找到例如val = 5的第一个项目。对于上面的数据,我希望获得名称为“nnn”(不是“ooo”)的项目,并在找到第一个项目后结束流程。与 Array.find 类似,我想避免在找到匹配项后处理其余数据。
一种无聊的旧方法是这样的,带有一个循环,但这……很无聊,而且不像可爱的数组函数那么整洁:)
let found
// loop through all data entries in the outer array
for (const d of data) {
// attempt to find a matching item in the inner array.
// using array.find means we stop at the first match, yay!
const theItem = d.arr.find(item => {
return myPredicate(item)
})
// we also need to break out of the loop. ugh!
if (theItem) {
found = theItem
break
}
}
// return what we found (may be undefined)
return found
现在,我意识到我可以用 find() 和 some() 做一些事情,比如说,类似于这里的答案ES6 - Finding data in nested arrays,但问题是在外部数组上使用 find 意味着我们得到了外部数据数组的第一项,而我想要内部 arr 数组中的一项。
const outer = data.find(d => {
return d.arr.some(item => {
return myPredicate(item)
})
})
然后我将不得不再次处理外部以在 outer.arr 中找到项目,例如
outer.arr.find(item => myPredicate(item))
这不适合我,因为对 some(...) 的调用已经通过并找到了匹配的内部项目!
我认为这将是直截了当的,也许是这样,但出于某种原因,我陷入了这个小挑战。
我还查看了不错的遍历库(https://www.npmjs.com/package/traverse),但这似乎更多是关于遍历整个树,而不是在找到特定节点后停止并返回.
有人来挑战吗?;)
解决方案
最简单(虽然有点难看)的解决方案是在找到时将匹配分配给item
外部变量:
let foundNested;
data.some(subarr => (
subarr.some((item) => {
if (myPredicate(item)) {
foundNested = item;
return true;
}
});
});
您可以.reduce
用来避免分配给外部变量:
const myPredicate = ({ val }) => val === 5;
const data = [
{arr: [{val:6,name:'aaa'},{val:4,name:'bbb'},{val:8,name:'ccc'}]},
{arr: [{val:3,name:'mmm'},{val:5,name:'nnn'},{val:9,name:'ppp'},{val:5,name:'ooo'}]}
];
const found = data.reduce((a, { arr }) => (
a ||
arr.find(myPredicate)
), null);
console.log(found);
问题是,reduce
不会短路 - 无论如何它都会完全迭代外部数组。对于真正的短路,我想我更喜欢使用for..of
循环:
const data = [
{arr: [{val:6,name:'aaa'},{val:4,name:'bbb'},{val:8,name:'ccc'}]},
{arr: [{val:3,name:'mmm'},{val:5,name:'nnn'},{val:9,name:'ppp'},{val:5,name:'ooo'}]}
];
function findNested(outerArr, myPredicate) {
for (const { arr } of outerArr) {
for (const item of arr) {
if (myPredicate(item)) {
return item;
}
}
}
}
const myPredicate = ({ val }) => val === 5;
console.log(findNested(data, myPredicate));
推荐阅读
- javascript - display result in a div after submitting in React
- c++ - C ++获得树的最低级别
- php - 我如何计算php中的百分比?
- python - 条形图中限制为 10
- android - android中自定义textview上的InvocationTargetException
- javascript - 奥多 15 | 带有 useService Hook 的 act_window 在 setup 方法中的自定义 OWL 组件中不起作用
- c# - 从方法中捕获异常
- python - 来自熊猫数据框的 3d 绘图/散点 xyz 坐标
- python-3.x - 更改熊猫图中的 x 轴刻度
- sympy - 是否可以用 sympy 简化(不求解)微分方程组?