问题
I have this data structure:
[{
id : 1,
name : "Item 1",
subItems : [{
id : 1,
name : "SubItem 1"
},{
id : 2,
name : "SubItem 2"
}
]
}, {
id : 2,
name : "Item 2",
subItems : [{
id : 3,
name : "SubItem 3"
}, {
id : 4,
name : "SubItem 4"
}
]
}]
I make the following call to a web service to get the items:
this.dataService.get("items")
Returned is an Observable<Item[]>
. What Observable operators can I use to only get a concatenated list of SubItems? I would like to end up with something like this:
[{
id : 1,
name : "SubItem 1"
}, {
id : 2,
name : "SubItem 2"
},
{
id : 3,
name : "SubItem 3"
}, {
id : 4,
name : "SubItem 4"
}]
Should I use something like flatMap
or concat
?
回答1:
Provided it is a typo and the second element has subItems
as well (and not searchProfiles
), you don't need flatMap or any thing of the sort, you can do it in a plain map using js array operators:
var transformed = [].concat(...result.map(item => item.subItems));
or in your case
httpResult$.map(result => [].concat(...result.map(item => item.subItems))
if the use of different keys is deliberate, your internal map will require a bit more logic but the mapping will be quite the same
回答2:
You want to first map()
operator to extract only fields you need and them flatten the arrays of objects with concatAll()
(it's a little trick with higher order Observables, see Subscribing to a nested Observable for more info):
var data = [{
id : 1,
name : "Item 1",
subItems : [
{ id : 1, name : "SubItem 1" },
{ id : 2, name : "SubItem 2" }
]
}, {
id : 2,
name : "Item 2",
searchProfiles : [
{ id : 3, name : "SubItem 3" },
{ id : 4, name : "SubItem 4" }
]
}];
Observable.from(data)
.map(item => {
if (item.searchProfiles) {
return item.searchProfiles;
} else if (item.subItems) {
return item.subItems
}
})
.concatAll()
.subscribe(val => console.log(val));
This prints to console:
{ id: 1, name: 'SubItem 1' }
{ id: 2, name: 'SubItem 2' }
{ id: 3, name: 'SubItem 3' }
{ id: 4, name: 'SubItem 4' }
Alternatively, if you really want the output as a single array then you can add toArray()
operator between .concatAll()
and .subscribe(...)
and you'll receive:
[ { id: 1, name: 'SubItem 1' },
{ id: 2, name: 'SubItem 2' },
{ id: 3, name: 'SubItem 3' },
{ id: 4, name: 'SubItem 4' } ]
来源:https://stackoverflow.com/questions/40346728/merge-subarrays-using-observables