5

I am trying to flatten an array of objects of arrays. For example, we might have something like so:

[{ numbers: [1, 2, 3] }, { numbers: [4, 5] }, { numbers: [6] }]

I would like to flatten it into:

[1, 2, 3, 4, 5, 6]

I have a working solution doing something like this:

const arr = [{ numbers: [1, 2, 3] }, { numbers: [4, 5] }, { numbers: [6] }];
const almostFlattened = arr.map((obj) => obj.numbers);
const flattened = [].concat.apply([], almostFlattened);
console.log(flattened);

Does anyone know of an easier or more performant solution here, preferably without the almostFlattened middle step?

6 Answers 6

13

You can try Array.reduce(), and flatten the numbers' arrays by concatenating the numbers with the accumulator:

const arr = [{ numbers: [1, 2, 3] }, { numbers: [4, 5] }, { numbers: [6] }];

const result = arr.reduce((r, obj) => r.concat(obj.numbers), []);

console.log(result);

Another option is Array.flatMap() (not supported by IE/Edge):

const arr = [{ numbers: [1, 2, 3] }, { numbers: [4, 5] }, { numbers: [6] }];

const result = arr.flatMap(obj => obj.numbers);

console.log(result);

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

1 Comment

you could also consolidate the push and return to => ( r.push(...obj.numbers), r )
5

Why not just use what you have, but inline? There's no need to declare a middle variable almostFlattened when you can put the .map call as part of the arguments to .concat:

const arr = [{ numbers: [1, 2, 3] }, { numbers: [4, 5] }, { numbers: [6] }]
const result = [].concat(...arr.map(o => o.numbers));
console.log(result)

1 Comment

Right, I just added the almostFlattened variable to explicitly highlight that middle step I am taking. My actual code is doing it inline.
1

Use the spread syntax with reduce:

const input = [{ numbers: [1, 2, 3] }, { numbers: [4, 5] }, { numbers: [6] }]
const output = input.reduce(((outputSoFar, { numbers }) => [...outputSoFar, ...numbers]), []);
console.log(output);

Comments

1

FlatMap is great

const data = [{ numbers: [1, 2, 3] }, { numbers: [4, 5] }, { numbers: [6] }]

data.flatMap(n => n.numbers)

If you want to flatten object with arrays:

Object.values({one: [1,2,3], two: [4,5,6]}).flat()

Comments

0

I also figured I would throw this out there in case anyone is using something like lodash/underscore (did not know this function existed at the time I posted the question):

const arr = [{ numbers: [1, 2, 3] }, { numbers: [4, 5] }, { numbers: [6] }];
const flattened = _.flatten(arr, 'numbers');
console.log(flattened);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.js"></script>

Comments

0

For much more deeply nested array of arrays such as: [1, 2, 3, [4, [5, [6, [7]]]]]

const flatten = (input, acc=[]) => {
    return input.reduce((_, current) => {
        if (Array.isArray(current)) return flatten(current, acc);  
        acc.push(current);
        return acc;
    }, []);
}

Usage:

console.log(flatten([1, 2, 3, [4, [5, [6, [7]]]]]));

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.