2

I am pretty new to javascript and I have an issue with flattening several arrays into one complete array using the reduce and concat function.

var array = [ [1, 3], [6, 6], [3, 3] ]; 

var finishedArray = function(array) {
var reducedArray = {};
var completeArray = {};


for (var i = 0; i < array.length; i++) {
    reducedArray[i] = array[i].reduce(function (a, b) {
        return a + b;
    });

    completeArray = reducedArray[i].concat(reducedArray[i + 1]);
}

return completeArray;

}

console.log(finishedArray(array));`

The error I get is : completeArray = reducedArray[i].concat(reducedArray[i + 1]);

TypeError: undefined is not a function

Why is that???

3
  • 3
    Arrays are [] not {}. Commented Jan 16, 2015 at 21:57
  • 1
    You question would be improved if you included you desired result. I assume you want an array that looks like [1,3,6,6,3,3] is that correct? Commented Jan 16, 2015 at 21:59
  • You are referencing reducedArray[i + 1] before it's been set by the for loop Commented Jan 16, 2015 at 22:02

4 Answers 4

5

the easy way:

var finishedArray = [ [1, 3], [6, 6], [3, 3] ].reduce(Function.apply.bind([].concat), [])

another nice option than can be more readable is using a named function, which lets you apply this transform to many arrays in many places without so much ugly boilerplate every time:

function flat(a,b){return a.concat(b);}

[[1,3],[6,6],[3,3]].reduce(flat);
[[7,3],[4,6],[8,1]].reduce(flat);

it's the shortest path to flatten many different arrays.

note you can also write the reusable in the same fast-but-ugly syntax as my first suggestion:

 var flat=Function.apply.bind([].concat);

also note that elclanrs shows an even simpler method that i really like:

 [].concat.apply([],[[1,3],[6,6],[3,3]]) 
Sign up to request clarification or add additional context in comments.

6 Comments

It's even easier: As the comment below the Q says, he messed up [] vs. {}.
@Someone: this is ES5. or js1.6 in old firefoxes. or anything with reduce and bind polyfills...
The easy-easy way [].concat.apply([],[[1,3],[6,6],[3,3]])
I don't think more concise is necessarily easier. I would do it like this: [[1,3],[6,6],[3,3]].reduce(function(a,b){return a.concat(b);})
@Someone: few things are necessary, but this feels pretty old to me already. i can't wait for readbility and laziness at the same time: arr.reduce( (a,b)=>a.concat(b) ) ...
|
3

@Dandavis has provided a perfectly good answer showing how to 'flatten' an jagged array—to turn an array of arrays into a single array containing all the elements of the original arrays. I'll try to explain why you're getting the error you are and hopefully improve your understanding of these methods.

First off, note that you declared reducedArray and completeArray as empty objects ({}). the syntax for creating an empty array is:

var reducedArray = [];
var completeArray = [];

Once you fix that though, you will still have problems. In this statement:

reducedArray[i] = array[i].reduce(function (a, b) {
    return a + b;
});

The reduce method will turn an input array (in this case array[i]) into a single value, by summing each consecutive item and returning the final result. Notice what this returns:

var array = [ [1, 3], [6, 6], [3, 3] ]; 
for (var i = 0; i < array.length; i++) {
    reducedArray[i] = array[i].reduce(function (a, b) {
        return a + b;
    });
}
console.log(reducedArray); // [4, 12, 6]

This means that reducedArray[i] is actually a number, not an array, and there is no concat method on the Number type. Because concat is undefined, you cannot call it like a function.

3 Comments

re-considering the part about "pretty new to javascript", and in reflection, I have come to believe this is the right approach to a good answer.
@dandavis Thanks, but I don't think you should have deleted your answer. It discusses a number of good approaches to solving the core problem, and would definitely be illustrative once OP has understood the original problems. The two answers seem to complement each other, IMO.
re-re-considering, i put it back up, it does have some decent examples. i still think an educational response is more apropos...
0

We can also do this using Arrow function like:

var array = [ [1, 3], [6, 6], [3, 3] ];
var finishedArray = array.reduce((e, f) => e.concat(f), []);

 


Demo:

var array = [ [1, 3], [6, 6], [3, 3] ];
var finishedArray = array.reduce((e, f) => e.concat(f), []);

// Output
console.log( finishedArray );

This will give output like:

[1, 3, 6, 6, 3, 3]

 


If you need unique values in this finishedArray variable you can also do:

var uniqueArray = [...new Set(finishedArray)];

Demo:

var array = [ [1, 3], [6, 6], [3, 3] ];
var finishedArray = array.reduce((e, f) => e.concat(f), []);
var uniqueArray = [...new Set(finishedArray)];

// Output
console.log( uniqueArray );

This output for this is like:

[1, 3, 6]

Comments

0

There is an easier and shorter solution.

var array = [ [1, 3], [6, 6], [3, 3] ];
vat finishedArray = [].concat(...array);

Output: [1, 3, 6, 6, 3, 3].

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.