'Flattening nested array in JavaScript
I have a horrible looking array which looks like this:
EDIT:
array = [
{
Letters: [{ Letter: 'A' }, { Letter: 'B' }, { Letter: 'C' }],
Numbers: [{ Number: '1' }, { Number: '2' }, { Number: '3' }]
},
null,
{
Letters: [{ Letter: 'D' }, { Letter: 'E' }, { Letter: 'F' }, { Letter: 'G' }, { Letter: 'H' }],
Numbers: [{ Number: '4' }, { Number: '5' }, { Number: '6' }, { Number: '7' }]
}
];
And want the array to look like this:
flattenedArray = [a,b,c,1,2,3,d,e,f,g,h,4,5,6,7]
Unfortunately I cannot change the original formatting because that is the form received when merging two API responses that I am getting.
I have tried using:
var flattenedArray = [].concat.apply([], array);
But it just presents the array in the same format it was entered in.
I was wondering if anybody had any advice?
EDIT: I have tried implementing the suggestions given - thank you so much for your help. It seems it is a problem with the format of the list - unfortunately using the chrome console which is in a 'tree' format I cannot see the direct structure of the array output.
Thank you for all your help! EDIT 2: See above for the actual array, thank you for showing me how to see this!
Solution 1:[1]
If you have lodash, you can use:
_.flattenDeep(array)
You can also checkout their source code for ides on how to implement yourself if you prefer.
Solution 2:[2]
You can create recursive function using forEach() that will return new array.
var array = [[['a','b','c'],[1,2,3]],[],[['d','e','f','g','h'],[4,5,6,7]]]
function flat(data) {
var r = []
data.forEach(e => Array.isArray(e) ? r = r.concat(flat(e)) : r.push(e));
return r;
}
console.log(flat(array))
You can also use reduce() instead of forEach()
var array = [[['a','b','c'],[1,2,3]],[],[['d','e','f','g','h'],[4,5,6,7]]]
function flat(data) {
return data.reduce((r, e) => Array.isArray(e) ? r = r.concat(flat(e)) : r.push(e) && r, [])
}
console.log(flat(array))
As @Bergi suggested you can use reduce() like this.
data.reduce((r, e) => r.concat(Array.isArray(e) ? flat(e) : [e]), [])
Solution 3:[3]
It's nice to use a recursive function for such cases:
arr = [[['a','b','c'],[1,2,3]],[],[['d','e','f','g','h'],[4,5,6,7]]];
function flatten(arr) {
var result = [];
for (var i = 0, len = arr.length; i < len; i++) {
result = result.concat(Array.isArray(arr[i])? flatten(arr[i]) : [arr[i]]);
}
return result;
}
console.log(flatten(arr));
Solution 4:[4]
You could try the flatten function in Ramda.
R.flatten([1, 2, [3, 4], 5, [6, [7, 8, [9, [10, 11], 12]]]]);
//=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
Solution 5:[5]
Your Array format is not correct, you are missing commas(,). This is correct array.
var array = [[['a','b','c'],[1,2,3]],[],[['d','e','f','g','h'],[4,5,6,7]]];
var array = [[['a','b','c'],[1,2,3]],[],[['d','e','f','g','h'],[4,5,6,7]]];
var result = flatten(array);
function flatten(array) {
var flat = [];
if(array !== undefined){
var flat = [];
for (var i = 0; i < arguments.length; i++) {
if (arguments[i] instanceof Array) {
flat = flat.concat(flatten.apply(null, arguments[i]));
} else {
flat.push(arguments[i]);
}
}
}
return flat;
}
console.log(result);
Solution 6:[6]
No one thought of splicing in-place?
function flatten(array){
for (var i = 0; i < array.length; i++) {
if(array[i] instanceof Array){
array.splice.apply(array,[i,1].concat(array[i]));
i--;
}
};
return array;
}
One iteration, no recursion.
Solution 7:[7]
Implement flatten function using recursion and spread operator.
const a = [1,[2,[3,4],[5]],6];
const flatten = (arr) => {
const res = []
for(let i=0;i<arr.length;i++) {
if(!Array.isArray(arr[i])) res.push(arr[i]);
else res.push(...flatten(arr[i]));
}
return res;
}
console.log(flatten(a));
Solution 8:[8]
function steamrollArray(arr) {
var tmp = [];
arr.forEach(function(val){
if(Array.isArray(val))
tmp = tmp.concat(steamrollArray(val));
else
tmp.push(val);
});
console.log(tmp);
return tmp;
}
steamrollArray([1, [2], [3, [[4]]]]);
Solution 9:[9]
let arr = [1,2,[3,4]]
/* let newarr = arr.flat(); */
let newarr = Object.values(arr);
let arr2 = []
for(let val of Object.values(arr)) {
if(!Array.isArray(val)){
console.log(val)
arr2.push(val)
}
for ( let val2 of Object.values(val)){
arr2.push(val2)
}
}
console.log(arr2)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
