3

I have an array of objects and I'd like to return an array of all the ids. For example:

const arr = [
    {Locations:[{id:2129, Name: 'testAA'}, {id:3431, Name: 'testAB'}, {id:4373, Name: 'testAC'}]},
    {Locations:[{id:2545, Name: 'testBA'}, {id:3431, Name: 'testBB'}]}
];     

I'd like to return: [2129, 3431, 4373, 2545, 3431]

I've tried to following:

arr.map((value) => {
    let newarray = [];
    return newarray += value['Locations'].map(ID => ID.id);
});

This returns: ["2129,3431,4373", "2545,3431"]

How do I combine those two arrays?

0

6 Answers 6

5

Given that your input and output aren't a 1-to-1 mapping, this doesn't seem like a great use-case for .map(). Instead, I'd consider using .map() only on the inner array, but using .reduce() on the outer.

const arr = [{Locations:[{id:2129, Name: 'testAA'}, {id:3431, Name: 'testAB'}, {id:4373, Name: 'testAC'}]},{Locations:[{id:2545, Name: 'testBA'}, {id:3431, Name: 'testBB'}]}];     

const result = arr.reduce((acc,{Locations}) => [...acc, ...Locations.map(i=>i.id)], []);

console.log(result);

As an alternative, you could use .concat():

const arr = [{Locations:[{id:2129, Name: 'testAA'}, {id:3431, Name: 'testAB'}, {id:4373, Name: 'testAC'}]},{Locations:[{id:2545, Name: 'testBA'}, {id:3431, Name: 'testBB'}]}];     

const result = arr.reduce((acc,{Locations}) => acc.concat(Locations.map(i=>i.id)), []);

console.log(result);

Sign up to request clarification or add additional context in comments.

5 Comments

When the accumulator and subarray get flattened but you're producing an output array, flatMap is the right tool (but this is good if browser compatibility prohibit, although if this was the case [].concat() is a good flatMap alternative). This looks like quadratic time due to ...acc.
@ggorlen Thanks. I've included an alternative.
concat does the same thing--makes a totally new array on each iteration, unfortunately. If you have to use reduce, it's important to return a; so that the result array isn't rebuilt arr.length times. But then it gets very ugly-looking which shows that reduce(...., []) is an antipattern (should be map). Prefer Mamum's answer or mine if compatibility is needed. Feel free to benchmark them.
@ggorlen I don't disagree, just doesn't make much sense to alter my answer to mimic alternatives that were already provided :)
Absolutely, and it's not a bad answer by any means! Generally most of the data is going to be small, so I don't mean to be overly pedantic.
2

You can try with Array.prototype.flatMap():

The flatMap() method first maps each element using a mapping function, then flattens the result into a new array. It is identical to a map() followed by a flat() of depth 1, but flatMap() is often quite useful, as merging both into one method is slightly more efficient.

and Array.prototype.map()

The map() method creates a new array with the results of calling a provided function on every element in the calling array.

const arr = [
    {Locations:[{id:2129, Name: 'testAA'}, {id:3431, Name: 'testAB'}, {id:4373, Name: 'testAC'}]},
    {Locations:[{id:2545, Name: 'testBA'}, {id:3431, Name: 'testBB'}]}
];
const newarray = arr.flatMap(i => i.Locations.map(j => j.id));
console.log(newarray);

1 Comment

Just a note- Not very cross-browser compatible.
1

Try using

arr.map((value) => {
    let newarray = [];
    return newarray += value['Locations'].map(ID => ID.id);
}).join(',').split(',').map((value) => parseInt(value, 10));

Here's the "chain of events": ["2129,3431,4373", "2545,3431"] -> "2129,3431,4373,2545,3431" -> ["2129","3431","4373","2545","3431"] -> [2129, 3431, 4373, 2545, 3431]

1 Comment

Now that I look at it, Tyler's answer above is much cleaner and better- use that one instead.
0

I like Tyler Roppers answer

concat the two arrays https://www.w3schools.com/jsref/jsref_concat_array.asp

haven't tested by maybe return newarray.concat(value['Locations'].map(ID => ID.id));

Could also run something like this which might be a bit cleaner.

arr.map((value) => {
    let newArray = [];
    Locations.map((location) => {
        return newArray.push(location.id)
    });
    if(newArray.length) return newArray;
    return null;
}

Comments

0

You don't have two arrays there, you have an array of two concatenated strings. You don't need the newarray[] at all; .map() returns a new array for you.

When you get that you can combine it with a reduce().

What you want will look like this:

arr
    .map((value) => value['Locations']
        .map(ID => ID.id))
    .reduce((accum, arr)=>accum.concat(arr));

Comments

0

Array#flatMap is the correct tool for this scenario, but if browser compatibility prohibits its use, you can flatten using Array#concat and spread syntax:

const arr = [{Locations:[{id:2129, Name: 'testAA'}, {id:3431, Name: 'testAB'}, {id:4373, Name: 'testAC'}]}, {Locations:[{id:2545, Name: 'testBA'}, {id:3431, Name: 'testBB'}]}];

console.log([].concat(...arr.map(e => e.Locations.map(e => e.id))));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.