我能够在下面的javascript中找到该对象,但是它非常可怕,并且我做了两次查找。
我会对一种更好的方法感兴趣,而这种方法不涉及我目前未使用的lodash。
const statuses = [{
items: [{
id: 1,
name: 'foo'
}, {
id: 5,
name: 'bar'
}]
}, {
items: [{
id: 1,
name: 'mook'
}, {
id: 2,
name: 'none'
}, {
id: 3,
name: 'soot'
}]
}]
const selected = statuses.find(status => {
const none = status.items.find(alert => {
return alert.name === 'none';
});
return !!none;
});
console.log(selected)
const a = selected.items.find(s => s.name === 'none');
console.log(a)
答案 0 :(得分:0)
您可以将所有状态项与reduce()
组合成一个数组,然后只需find()
一次:
const statuses = [{
items: [{
id: 1,
name: 'foo'
}, {
id: 5,
name: 'bar'
}]
}, {
items: [{
id: 1,
name: 'mook'
}, {
id: 2,
name: 'none'
}, {
id: 3,
name: 'soot'
}]
}]
const theNones = statuses
.reduce(function(s, t) { return s.items.concat(t.items); })
.find(function(i) { return i.name === 'none'; });
console.log(theNones);
答案 1 :(得分:0)
您可以像这样使用嵌套的some
和find
。这样,一旦找到匹配项,您就可以跳过该操作。
const statuses=[{items:[{id:1,name:'foo'},{id:5,name:'bar'}]},{items:[{id:1,name:'mook'},{id:2,name:'none'},{id:3,name:'soot'}]}];
let found;
statuses.some(a => {
const s = a.items.find(i => i.name === "none");
if (s) {
found = s;
return true
} else {
return false
}
})
console.log(found)
您可以使用map
,concat
和find
做类似的事情。这有点慢,但看起来更整洁。
const statuses=[{items:[{id:1,name:'foo'},{id:5,name:'bar'}]},{items:[{id:1,name:'mook'},{id:2,name:'none'},{id:3,name:'soot'}]}]
const found = [].concat(...statuses.map(a => a.items))
.find(a => a.name === "none")
console.log(found)
这里有jsperf
与您的代码进行比较。第一个是最快的。
答案 2 :(得分:0)
注意:Array.prototype.flatMap
是find
的语言,不是该语言的一部分,但在当今的大多数环境(包括Babel)中都可以使用。
var arr = [{items:[{id:1,name:'foo'},{id:5,name:'bar'}]},{items:[{id:1,name:'mook'},{id:2,name:'none'},{id:3,name:'soot'}]}]
console.log(
arr
.flatMap(({ items }) => items)
.find(({
name
}) => name === 'none')
)
我们可以通过填充(通过map + reduce)来填充平面图:
var arr = [{items:[{id:1,name:'foo'},{id:5,name:'bar'}]},{items:[{id:1,name:'mook'},{id:2,name:'none'},{id:3,name:'soot'}]}];
console.log(
arr
.map(({ items }) => items)
.reduce((items1, items2) => items1.concat(items2))
.find(({
name
}) => name === 'none')
)
您还可以减少结果:
var arr = [{items:[{id:1,name:'foo'},{id:5,name:'bar'}]},{items:[{id:1,name:'mook'},{id:2,name:'none'},{id:3,name:'soot'}]}]
console.log(
arr.reduce((result, {
items
}) =>
result ? result : items.find(({
name
}) => name === 'none'), null)
)
答案 3 :(得分:0)
一个reduce函数(对所有内容进行一次迭代),该函数返回符合条件的任何对象的数组:
const [firstOne, ...others] = statuses.reduce((found, group) => found.concat(group.items.filter(item => item.name === 'none')), [])
由于您似乎首先对遇到的第一个想法感兴趣,因此我使用了重组方法来模仿您的find
想法。由于此操作仅对每个项目进行一次迭代,因此在性能方面要比替代答案更好,但是如果您确实对性能有所关注,那么for循环是您的最佳选择,因为返回值将使函数短路并给出您的价值:
const findFirstMatchByName = (name) => {
for (let group of statuses) {
for (let item of group.items) {
if (item.name === name) {
return item
}
}
}
}
findFirstMatchByName('none')