1

Let's assume i have this type of array:

[ [1, 2], [3, 4] ]

What i need to do is to get nested elements on the higher layer, to make it look like:

[1, 2, 3, 4]

I am trying to reach that in functional way, so the code look's like this:

const arr = [ [1, 2], [3, 4] ]
const f = Array.from(arr, x => ...x)

But that comes up with Unexpected token ... error. So what's the way to do it right?

4
  • There’s Array.prototype.flat. Look at its polyfills. Commented Jan 1, 2019 at 19:39
  • Will the nested elements always be Arrays? Commented Jan 1, 2019 at 19:40
  • 1
    Your confusion stems from the fact that the spread syntax is not an operator. It's a contextual syntax. Commented Jan 1, 2019 at 19:40
  • @Xufox thank's for that! flat seems pretty good to me. Commented Jan 1, 2019 at 19:45

3 Answers 3

5

You can use the flat method of Array:

const inp = [ [1, 2], [3, 4] ];

console.log(inp.flat());

In your case, the spread syntax is not an operator that you can use in that way, that's why the error.

As @MarkMeyer correctly pointed out in the comments, the flat is not supported yet by Edge and Internet Explorer. In this case you could go for a solution with reduce:

const inp = [[1,2], [3,4]];
console.log(inp.reduce((acc, val) => acc.concat(...val), []));

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

5 Comments

Probably worth mentioning this does not (currently) work on Edge, Internet Explorer, or Node.
@PatrickRoberts which version are you using? it's working since chrome 69
@PatrickRoberts you can check the browser compatibility here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
chrome also supports flatMap
Oh, I had a flag set, that was my bad.
3

Array.from will produce an item for every item in the array passed in. It looks at the length of the passed in iterable and iterates over the indexes starting at 0. So no matter what you do in the callback (assuming it's valid), you're going to get an array of length 2 output if you pass in a two-element array.

reduce() is probably a better option here:

let arr = [ [1, 2], [3, 4] ]

let flat = arr.reduce((arr, item) => [...arr, ...item])
console.log(flat)

Comments

1

You could create an iterator for the array and spread the array by using another generator for nested arrays.

function* flat() {
    for (var item of this.slice()) {
        if (Array.isArray(item)) {
            item[Symbol.iterator] = flat;
            yield* item
        } else {
            yield item;
        }
    }
}

var array = [[1, 2], [3, 4, [5, 6]]];

array[Symbol.iterator] = flat;

console.log([...array]);

1 Comment

That's pretty cool. It might be nicer if flat() took the array as a parameter and was called recursively so you avoid the side effect of altering the sub arrays. But then you'd have to call [...flat(array)]

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.