我有一些来自Angular的优雅服务的数据看起来像这样(简要):
const obj = {
field: [
{
id: 1,
items: []
},
{
id: 2,
items: [ { wateva: 'wateva1' } ]
},
{
id: 3,
items: false
},
{
id: 4,
items: [ { yeah: 7 } ]
}
]
}
好吧,我的任务就是收集所有非空的数组项。 我的解决方案(实际上我的解决方案是用TypeScript和Angular 5编写的,但是为了使它更简单易懂,它将会像......):
function getItems() {
const items = [];
obj.field.forEach(currentField => {
if (currentField.items && currentField.items.length) {
currentField.items.forEach(currentItem => items.push(currentItem));
}
});
return items;
}
是的,它很简单,它按预期工作(当前的一个将返回......):
[ { wateva: 'wateva1' }, { yeah: 7 } ]
现在我的问题......如何使我的解决方案正常运行?我想摆脱我的新变量 items ,我不想推入那个变量,我只想在一个动作中返回结果。任何帮助将不胜感激。
P.S。不接受第3个图书馆的建议:)
答案 0 :(得分:2)
如果你可以使用es6(因为你提到你正在使用打字稿,那应该没问题),你可以通过组合concat
,map
将其变成一个很好的功能性单行程, filter
和传播运营商:
const obj = {
field: [
{
id: 1,
items: []
},
{
id: 2,
items: [ { wateva: 'wateva1' } ]
},
{
id: 3,
items: false
},
{
id: 4,
items: [ { yeah: 7 } ]
}
]
}
function getItems(obj) {
return [].concat(...obj.field.map(o => o.items).filter(Array.isArray))
}
console.log(getItems(obj))
答案 1 :(得分:1)
您可以使用flatMap
(stage 3)。 flatMap
符合Fantasy Land的chain
规范。
data.field.flatMap
(({ items }) =>
Array.isArray (items) ? items : []
)
// [ { wateva: 'wateva1' }, { yeah: 7 } ]
您可以在没有它的环境中对其进行填充
Array.prototype.flatMap = function (f) {
return this.reduce
( (acc, x) =>
acc.concat (f (x))
, []
)
}
完整的程序演示
Array.prototype.flatMap = function (f) {
return this.reduce
( (acc, x) =>
acc.concat (f (x))
, []
)
}
const data =
{ field:
[ { id: 1, items: [] }
, { id: 2, items: [ { wateva: 'wateva1' } ] }
, { id: 3, items: false }
, { id: 4, items: [ { yeah: 7 } ] }
]
}
const result =
data.field.flatMap
(({ items }) =>
Array.isArray (items) ? items : []
)
console.log (result)
// [ { wateva: 'wateva1' }, { yeah: 7 } ]

答案 2 :(得分:0)
您可以使用Array.reduce
和spread运算符累积到空数组:
obj.field.reduce(
(acc, current) => current.items && current.items.length > 0 ? [...acc, ...current.items] : acc, [])
);
答案 3 :(得分:0)
使用Array.prototype.reduce,object destructuring, and spread assignments:
function getItems({ field }) {
return field.reduce((result, { items }) =>
items instanceof Array ?
items.reduce((items, item) => [...items, item], result) :
result
, []);
}