0

I'm new to JS and I have a task to flatten an array. What I have is [1,2,[3,4]] and I have to turn it into [1,2,3,4]. I use the following approach

function flatten(arr){ return arr.reduce(function(a, b) { return a.concat(b); }); } 

But it says concat is not a function.

Array.isArray(arr); //returns true 

Can someone tell me what to do here :)

1
  • 3
    Hint: you are testing to see if arr is an array, but calling concat on a. Why don't you test to see if a is an array? :) Commented Dec 28, 2016 at 14:02

7 Answers 7

3

Your arr value is [1,2,[3,4]]. That's an array with three entries: the number 1, the number 2, and the array [3,4].

The first two arguments to a reduce callback are

  1. the accumulator (which is the return value of the previous invocation of the callback) and
  2. a value taken in sequence from the array.

You don't supply an initial accumulator in your code, so that means the first call to the reduce callback accepts the first two entries as arguments (i.e., the first element of the array is used as an accumulator). concat is not a function because the initial value of a is a number, not an array. You tested to see if arr was an array, but did not test to see if a was an array.

The clear solution here is to supply an initial value to use as an accumulator:

function flatten(arr){ return arr.reduce(function(a, b) { return a.concat(b); }, []); } 

This creates an empty array (with []) and then supplies it as the a value for the first call to the reduce callback.

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

1 Comment

So at the first step it will concatanate [] + 1 and it will be [1] ?
1

You can use this solution:

 var array = [].concat.apply([], [1,2,[3,4]]); console.log(array);

Comments

1

DOCS about the array says

The JavaScript Array object is a global object that is used in the construction of arrays; which are high-level, list-like objects.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array

In your example for reduce you will have to provide an initial value which can b an empty array.

var flattened = [1,2,[3,4]].reduce(function(a, b) { return a.concat(b); }, []); console.log(flattened)

Comments

1

You just need to provide array [] after the callback function as initial value to reduce, otherwise that value will be first element of your array. So in your code in first iteration of reduce you are trying to do this a.concat(b) where a is 1 and b is 2 and that throws the error.

function flatten(arr) { return arr.reduce(function(a, b) { return a.concat(b); }, []); } console.log(flatten([1, 2, [3, 4]]))

Comments

1

concat is expecting an Array of values to join with another Array. The reason this is failing is because your Array isn't a full matrix.

The problem with your array is that it wouldn't be wise to create a single hard coded solution for that specific Array, you should probably create a recursive function like:

function flattenArr(arr) { const newArr = [] function recursiveFlat(a) { if(!Array.isArray(a)) { newArr.push(a); } else { for (let i = 0; i < a.length; i++) { if(Array.isArray(a[i])) { recursiveFlat(a[i]); } else { newArr.push(a[i]); } } } } arr.forEach(item => recursiveFlat(item)); return newArr; } arr = [1, 2, [3, 4]] console.log(flattenArr(arr))

That way it will always flatten the array no matter the shape.

Comments

0

You just make sure that arr is an array. But,you call concat on a. test this: if(a instanceof Array)

Comments

0

You can use Array.prototype.concat() combined with Spread syntax:

var flattened = [].concat.call([], ...[1, 2, [3, 4]]); console.log(flattened);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.