Tob*_*oby 14 javascript arrays ecmascript-6
在ES6中使用find或者filter我很乐意迭代使用值来查找数组中的元素.
但是,我试图根据嵌套数组中的值从父数组中获取值.
例如,在此数据结构中:
products: [
{
id: 01,
items: [
{
id: 01,
name: 'apple'
},
{
id: 02,
name: 'banana'
},
{
id: 03,
name: 'orange'
}
]
},
{
id: 02,
items: [
{
id: 01,
name: 'carrot'
},
{
id: 02,
name: 'lettuce'
},
{
id: 03,
name: 'peas'
}
]
},
{
id: 03,
items: [
{
id: 01,
name: 'eggs'
},
{
id: 02,
name: 'bread'
},
{
id: 03,
name: 'milk'
}
]
}
]
Run Code Online (Sandbox Code Playgroud)
如果我知道对象name或id对象milk,有没有办法找出它嵌套在其中的元素的id?
目前我有这个:
products.find((product) => {
product.find((prod) => {
return prod.name === 'milk';
});
});
Run Code Online (Sandbox Code Playgroud)
其中只返回包含的对象milk.
Ber*_*rgi 37
你必须从外部的回调中返回一些东西find.实际上,对于内部迭代,您不应该使用find而是some返回一个布尔值,表示在arrray中是否存在与条件匹配的元素:
products.find((product) => {
return product.items.some((item) => {
//^^^^^^
return item.name === 'milk';
});
});
Run Code Online (Sandbox Code Playgroud)
或简而言之:
products.find(product => product.items.some(item => item.name === 'milk'));
Run Code Online (Sandbox Code Playgroud)
然后检查是否find找到了某些东西(不是null!)并得到它.id,结果应该是03.或者,您可以filter将包含牛奶的产品作为项目,然后将所有结果映射到其ID:
products.filter(product =>
product.items.some(item => item.name === 'milk');
).map(product =>
product.id
) // [03]
Run Code Online (Sandbox Code Playgroud)
ari*_*iel 18
我知道你提到了 ES6,但在这种情况下(如果你想返回内部对象)我相信使用for/of而不是map/ reduce/更好find:
for (let p of products) {
for (let i of p.items) {
if (i.name === 'milk') return i;
}
}
Run Code Online (Sandbox Code Playgroud)
小智 12
另一种方法:
products
.map((category) => category.items)
.flat()
.find((product) => product.name === 'milk');
Run Code Online (Sandbox Code Playgroud)
更新
正如 Ricardo Marimon 评论的那样,reduce 不会中断,因此它会继续搜索数组,因此考虑到这一点,因为我不喜欢使用 for 循环命令式编程方式,所以可以通过改变所使用的数组来提前中断reduce ,但这也很糟糕,因此也可以制作副本并改变副本。
// slice creates a copy of products
return products.slice(0).reduce((prev, product, i, arr) => {
console.log(i);
const findItem = prev || product.items.find(item => item.name === 'milk');
if (typeof findItem !== 'undefined') arr.splice(1); // ejects early
return findItem;
}, undefined);
Run Code Online (Sandbox Code Playgroud)
const products = [
{id: 1, items: [
{id: 1, name: 'apple'},
{id: 2, name: 'banana'},
{id: 3, name: 'orange'}
]},
{id: 2, items: [
{id: 1, name: 'carrot'},
{id: 2, name: 'lettuce'},
{id: 3, name: 'milk'}
]},
{id: 3, items: [
{id: 1, name: 'eggs'},
{id: 2, name: 'bread'},
{id: 3, name: 'peas'}
]}
];
const findItem = products.slice(0).reduce((prev, product, i, arr) => {
console.log(i);
const findItem = prev || product.items.find(item => item.name === 'milk');
if (typeof findItem !== 'undefined') arr.splice(1); // ejects early
return findItem;
}, undefined);
console.log(findItem);Run Code Online (Sandbox Code Playgroud)
老的
接受的答案并不适合我,因为我想要内部查找的结果,使用两者总是给我外部过滤/查找的结果,并且我必须使用结果数组再次查找该值。
因此,我使用了带有短路的减少来获得内部结果。
// undefined as the initial value is necessary, otherwise it gets the first value of the array instead.
return products.reduce((prev, product) => prev || product.items.find(item => item.name === 'milk'), undefined);
Run Code Online (Sandbox Code Playgroud)
const products = [
{id: 1, items: [
{id: 1, name: 'apple'},
{id: 2, name: 'banana'},
{id: 3, name: 'orange'}
]},
{id: 2, items: [
{id: 1, name: 'carrot'},
{id: 2, name: 'lettuce'},
{id: 3, name: 'peas'}
]},
{id: 3, items: [
{id: 1, name: 'eggs'},
{id: 2, name: 'bread'},
{id: 3, name: 'milk'}
]}
];
console.log(products.reduce((prev, product) => prev || product.items.find(item => item.name === 'milk'), undefined));Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16974 次 |
| 最近记录: |