I've got array of objects, where I take only locations array. My goal is to merge these locations array to one array, however I fail to do so and get empty array. This is how I do it:
let results = [{
id: '1',
locations: ['aaaa', 'bbbbbb', 'cccccc']
},
{
id: '2',
locations: []
},
{
id: '3',
locations: ['ddd', 'aaadsad', 'sefd']
},
{
id: '4',
locations: ['ffff', 'eeee', 'sfdsfsd']
},
];
const locationIds = [].concat.apply([], ...results.filter(s => s.locations && s.locations.length > 0).map(({
locations
}) => ({
locations
})));
console.log(locationIds);
I've got array of objects, where I take only locations array. My goal is to merge these locations array to one array, however I fail to do so and get empty array. This is how I do it:
let results = [{
id: '1',
locations: ['aaaa', 'bbbbbb', 'cccccc']
},
{
id: '2',
locations: []
},
{
id: '3',
locations: ['ddd', 'aaadsad', 'sefd']
},
{
id: '4',
locations: ['ffff', 'eeee', 'sfdsfsd']
},
];
const locationIds = [].concat.apply([], ...results.filter(s => s.locations && s.locations.length > 0).map(({
locations
}) => ({
locations
})));
console.log(locationIds);
what I am doing wrong here? The result should be
['aaaa', 'bbbbbb', 'cccccc', 'ddd', 'aaadsad', 'sefd', 'ffff', 'eeee', 'sfdsfsd'];
5 Answers
Reset to default 8You don't need filter
here. Just use map
method by passing a callback provided function which is applied for every item on the array.
let results = [{ id: '1', locations: ['aaaa', 'bbbbbb', 'cccccc'] }, { id: '2', locations: [] }, { id: '3', locations: ['ddd', 'aaadsad', 'sefd'] }, { id: '4', locations: ['ffff', 'eeee', 'sfdsfsd'] }, ];
const locationIds = [].concat(...results.map(s => s.locations));
console.log(locationIds);
You can try with flatMap()
:
The
flatMap()
method first maps each element using a mapping function, then flattens the result into a new array. It is identical to amap()
followed by aflat()
of depth 1, butflatMap()
is often quite useful, as merging both into one method is slightly more efficient.
let results = [{
id: '1',
locations: ['aaaa', 'bbbbbb', 'cccccc']
},
{
id: '2',
locations: []
},
{
id: '3',
locations: ['ddd', 'aaadsad', 'sefd']
},
{
id: '4',
locations: ['ffff', 'eeee', 'sfdsfsd']
},
];
const locationIds = results.flatMap(i => i.locations);
console.log(locationIds);
You could taka a Array#flatMap
with the wanted property. If the property is not given, add a default array || []
.
let results = [{ id: '1', locations: ['aaaa', 'bbbbbb', 'cccccc'] }, { id: '2', locations: [] }, { id: '3', locations: ['ddd', 'aaadsad', 'sefd'] }, { id: '4', locations: ['ffff', 'eeee', 'sfdsfsd'] }],
locationIds = results.flatMap(({ locations }) => locations);
console.log(locationIds);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Can also solve using the Reduce function from Array.prototype.
var newResults = results.reduce(function(acc, curr) {
return acc.concat(curr.locations)
},[]
)
hope this helps
I spent too long on this not to post my own solution - interesting puzzle for me, although the other answers are no doubt more performant and readable. It uses the same sort of strategy as your original post, which might help point out where it went wrong.
const locationIds = [].concat
.apply([], results.filter(result =>
result.locations && result.locations.length > 0)
.map(result => { return result.locations }));