简体   繁体   中英

Flatten array of objects of arrays JavaScript

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?

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);

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)

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);

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/lodash@2.4.2/lodash.js"></script>

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()

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]]]]]));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM