0

Say I have an array: [['TEST1'], ['TEST2'], ['TEST3'], ['TEST4'], ['TEST5']] and I want to move all the elements to the "top" level of the array, so it would end up like so:

['TEST1', 'TEST2', 'TEST3', 'TEST4', 'TEST5']

I have a few mockups below, but I'm wondering what the recommended route might be.

var test = [['TEST1'], ['TEST2'], ['TEST3'], ['TEST4'], ['TEST5']];
var testarr = [];

test.forEach(function(e){
  testarr.push(e[0]);
})
console.log(testarr);

Or

var test = [['TEST1'], ['TEST2'], ['TEST3'], ['TEST4'], ['TEST5']];

for (i = 0; n = test.length, i < n; i++){
  test[i] = test[i][0]
}
console.log(test);

Output of both:

[ 'TEST1', 'TEST2', 'TEST3', 'TEST4', 'TEST5' ]
David Metcalfe
  • 2,237
  • 1
  • 31
  • 44
  • i am sure, there is a dupe target. – Nina Scholz Oct 06 '17 at 19:40
  • 1
    _"what the recommended route might be"_ Whichever route works best for you – Patrick Evans Oct 06 '17 at 19:40
  • 1
    Same question with native solutions: https://stackoverflow.com/questions/10865025/merge-flatten-an-array-of-arrays-in-javascript –  Oct 06 '17 at 19:41
  • 1
    You might want to look at [Merge/flatten an array of arrays in JavaScript?](https://stackoverflow.com/q/10865025/218196) for inspiration. – Felix Kling Oct 06 '17 at 19:41
  • @PatrickEvans Well a solution I put together in my ignorance might end up performing very poorly down the road as it scales up. I'm just trying to get a feel for proper solutions here. – David Metcalfe Oct 06 '17 at 19:42

7 Answers7

3

I would use map:

ES6

var out = test.map(el => el[0]);

ES5

var out = test.map(function (el) {
  return el[0];
});

DEMO

Andy
  • 61,948
  • 13
  • 68
  • 95
2

I'd stick with the first approach. It is much more concise, and less likely to fail. The second is somewhat difficult to understand if you're going in not knowing what it is supposed to do.

That being said, if you aren't just doing this to learn and actually plan to use this code for something, I recommend going with one of the proposed solutions from this thread instead. My pick of the litter:

var arrays = [['TEST1'], ['TEST2'], ['TEST3'], ['TEST4'], ['TEST5']];
var result = [].concat.apply([], arrays);
stelioslogothetis
  • 9,371
  • 3
  • 28
  • 53
2

You'd either use reduce, or destructure it in a es6 environment

let test = [['TEST1'], ['TEST2'], ['TEST3'], ['TEST4'], ['TEST5']];
console.log(test.reduce((a,b) => a.concat(b), []));
console.log([].concat(...test));

If you have a multidimensional array, you could use

const flat = e => e.reduce(
    (a, b) => a.concat(Array.isArray(b) ? flat(b) : b), []
);
baao
  • 71,625
  • 17
  • 143
  • 203
1

The first approach is much cleaner and doesn't open up the possibility of bugs that can creep in using the counter in the second approach. This is the exact reason that .forEach() is preferred over traditional counting loops with arrays.

Having said that, the better approach would be to use .map() as this works very much like .forEach(), but returns a new array, saving you the trouble of explicitly declaring one and removing the need to push() into the right index of the original array:

var test = [['TEST1'], ['TEST2'], ['TEST3'], ['TEST4'], ['TEST5']];
var testarr = test.map(e => { return e[0]; } );
console.log(testarr);
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
1

What your looking for is array flattening and can be done by:

var array = [['TEST1'], ['TEST2'], ['TEST3'], ['TEST4'], ['TEST5']]
[].concat.apply([], array);
1

For the case when you want to change array in different array, the tool for the job is map function instead of forEach. It is cleaner because you don't need additional variable declaration before, and you can use poor functions inside.

var testarr = test.map(function(e){
 return e[0];
});

forEach function purpose is to loop over an array, not change it. Such looping can be used for doing side effects, but in this particular case, you don't want the side effects but clean and poor transformation between two arrays, and for that use map.

Maciej Sikora
  • 19,374
  • 4
  • 49
  • 50
0

You can try the below method

const input = [
  ['TEST1'],
  ['TEST2'],
  ['TEST3'],
  ['TEST4'],
  ['TEST5']
]
function flattenDeep(input) {
    return input.reduce((accu, val) => Array.isArray(val) ? accu.concat(flattenDeep(val)):accu.concat(val), []);
}

console.log(flattenDeep(input));
user007
  • 189
  • 2
  • 13