Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastest way to Reduce and concat (or deep flatten) arrays of arrays

Tags:

javascript

As input, I receive two types of arrays of arrays made of x and y coordinates that represent polygon and multipolygon geometries.

array1 represents coordinates of a simple polygon geometry and array2 represent a multipolygon geometry:

var array1 = [[[0 , 0], [0, 1], [0 ,2]]]

var array2 = [[[[0, 0] , [0, 1], [0, 2]], [[1, 0], [1, 1], [1 ,2]]]]

Multipolygon geometry (array2) are represented by an array of arrays one level deeper than simple polygon geometry (array1).

I want to flatten those arrays in order to get those output:

   if input is array1 type : array1_out = [[0, 0, 0, 1, 0, 2]]

   if input is array2 type : array2_out = [[0, 0, 0, 1, 0, 2], [1, 0, 1, 1, 1, 2]]

My function is the following:

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

With this function above, the output for array1 is correct but the output of array2 is the following:

[[[0, 0] ,[0, 1], [0, 2]], [1, 0], [1, 1], [1, 2]]]

Is there a function to deeply flatten those two types of arrays?

Edit: Performance really matter here as the arrays are really big

like image 317
Below the Radar Avatar asked Aug 28 '15 13:08

Below the Radar


People also ask

Is concat faster than push?

concat returns a new array while push returns the length of updated array. Because concat creates a new array to hold the result of merged arrays, it's slower than push . For small arrays, both methods do not produce a significant difference in term of performance.

How do you reduce to flatten an array?

Flattening an array of arrays with the Reduce Method In JavaScript​​ We can use reduce to flatten nested amounts into a single array. We set the initial value to an empty array and then concatenate the current value to the total.

How do I combine multiple arrays into one?

The concat() method is used to merge two or more arrays. This method does not change the existing arrays, but instead returns a new array.


1 Answers

You can find a lot of helpful tools for manipulating arrays and collections in the Underscore and lodash libraries.

var arrays1 = [[[0 , 0], [0, 1], [0 ,2]]];
var array2 = [[[[0, 0] , [0, 1], [0, 2]], [[1, 0], [1, 1], [1 ,2]], ]];

var array1_out = flattenSimple(arrays1);
console.log(JSON.stringify(array1_out));

var array2_out = flattenMultiple(array2);
console.log(JSON.stringify(array2_out));

function flattenSimple(array_input) {    
    return _.flatten(array_input);
}

function flattenMultiple(array_input) {
    array_input = array_input[0];
    return array_input.map(function(a) {
        return _.flatten(a);
    });
}

Will produce the output you're looking for. I broke it into a flatten fn for each type, but you could use the same fn with a flag or more complex logic to know which type you're working with.

Fiddle

like image 144
davidmdem Avatar answered Oct 04 '22 00:10

davidmdem