Reputation: 425
How can I flatten an array without using flat()
by 1 level?
So far I have this
function flatten(array) {
let flattened = [];
for (let i = 0; i < array.length; i++) {
const current = array[i];
for (let j = 0; i < current.length; j++) {
flattened.push(current[j])
}
}
return flattened
}
console.log(flatten([['foo', 'bar'], ['baz', 'qux']]));
// -> ["foo", "bar", "baz", "qux"]
flatten([[1], [2], 3, 4, [5]]);
// -> [1, 2, 3, 4, 5]
flatten([false, [true, [false]], [true]]);
// -> [false, true, [false], true]
flatten([]);
// -> []
and its crashing my memory
Upvotes: 8
Views: 17397
Reputation: 11
const arrValue = [
['foo', 'bar', ['new', 'formula']], 'baz', 'qux', ['jews'],
['1', ['2', '3', ['4']]]
];
var flattered = [];
function flatteredArray(arr) {
for (let i = 0; i < arr.length; i++) {
const currentVal = arr[i];
if (!Array.isArray(currentVal)) {
flattered.push(currentVal);
continue;
} else {
flatteredArray(currentVal);
}
}
return flattered;
}
console.log(flatteredArray(arrValue));
Upvotes: 0
Reputation: 44
Everyone have different approach some are really good but here's one I learn durring leetcode and it have very less affect on memory and better runtime then other. Explanation: Goal is to achieve the functionality like Array.flat() without using it. Bellow function will take two parameter one is array and the second is the depth of flantening you want to achieve ( just like Array.flat(2). It will flanten two level depth of array and leaving the rest if any.). Inside a funtion there's a helper function which take index value and intial depth which is zer0. If the value is non array object then it will pushed into new result array. Otherwise it will call itself again with increment of depth level. This process of recursion keep running until depth is remain less then the funtion's second argument.
PS: I determine the runtime and memory performance from the leetcode.
var flat = function (arr, n) {
const res = [];
function helper(arr,depth) {
for(const val of arr) {
if(typeof(val) === 'object' && depth < n) {
helper(val,depth + 1);
} else {
res.push(val);
}
}
return res;
}
return helper(arr,0);
};
console.log(flat([1,2,3,[4,5,6],[7,8,[9,10,11],12],[13,14,15]],2));
// Expected output [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
console.log(flat([1,2,3,[4,5,6],[7,8,[9,10,11],12],[13,14,15]],1));
//Expected output [ 1, 2, 3, 4, 5, 6, 7, 8, [ 9, 10, 11 ], 12, 13, 14, 15 ];
Upvotes: -1
Reputation: 1
//For infinite nested array
const ar =[1,2,[3,[4,5,[6,7,[8,9]]]]]
function flatten(ar) {
return ar.reduce((ac, cur) =>{
if(Array.isArray(cur)){
return [...ac, ...flatten(cur)]
}
return [...ac, cur];
},[])
}
console.log(flatten(ar))
Upvotes: 0
Reputation: 1
let array = [1,[3,5],[6,8],[3,[0,9],7],4];
let flattened = [];
for (let i = 0; i < array.length; i++) {
const current = array[i];
if (!Array.isArray(current)) {
flattened.push(current);
}
for (let j = 0; j < current.length; j++) {
if (!Array.isArray(current[j])){
flattened.push(current[j]);
}else if (Array.isArray(current[j])){
let newle = current[j]
flattened.push(newle[0]);
flattened.push(newle[1]);
}
}
}
console.log(flattened);
Upvotes: 0
Reputation: 1
This worked for me:
function myFlattern(arr) {
let check;
do{
check=false;
for(let i=0;i<arr.length;i++)
{
if(Array.isArray(arr[i]))
{
check=true;
let x=arr[i];
arr.splice(i,1,...x);
}
}
}while(check)
return arr;
}
Upvotes: 0
Reputation: 1
var multiDimensionArray = [["a"],["b","c"],["d"]]; //array of arrays
var flatArray = Array.prototype.concat.apply([], multiDimensionArray); //flatten array of arrays
console.log(flatArray);
Upvotes: 0
Reputation: 21
//Using Recursion
const arr = [1, 2, 3, 4, [5, 6, [6, 7], 7, 8]]
let arr2 = [];
function flat(arr) {
arr.forEach(element => {
if (typeof (element) == 'object') {
flat(element);
} else {
arr2.push(element);
}
});
}
flat(arr);
console.log(arr2);
Upvotes: 2
Reputation: 4955
Suppose given flatten number list without using the flat function is:
let array = [2,3,[5,2,[6,[3, [4, 5, [5, 1, 3]]]],1,1],9];
//let array= [2,3,[5,2,[6,[3, [4, 5, [5, {"key":"value"}, 3]]]],1,1],9];
//achieve above commented nested array condition using second approach.
The best answer already given by @Mahipal that would be first approach i.e.
array.toString().split(',')
with number array conversion
array.toString().split(',').map(n => +n)
another approach would be using function recursion without toString()
function flatter(arr) {
if (!Array.isArray(arr) && (!isNaN(arr) || typeof arr === "object")) {
return arr;
}
return arr.reduce((a, b) => {
a.push(...[].concat(flatter(b)));
return a;
}, [])
}
flatter(array);
and output is:
[ 2, 3, 5, 2, 6, 3, 4, 5, 5, 1, 3, 1, 1, 9 ]
Hope this would help many ones.
Upvotes: 1
Reputation: 1915
There is another interesting way to do it.
const arr2 = [0, 1, 2, [5, [10, [3, 4]]]]
const arr2 = [0, 1, 2, [5, [10, [3, 4]]]]
console.log( JSON.parse('['+ JSON.stringify(arr2).replace(/\[/g, ' ').replace(/\]/g, ' ') + ']'))
Upvotes: 0
Reputation: 519
You can use the following method if your array have primitive data type and want to flat it completely:
arr.toString().split(',');
Upvotes: 2
Reputation: 29004
To flatten by a single level only, Array#concat()
can be leveraged. It accepts any amount of arguments, so an array can be spread into the function call:
[].concat(...arr)
This avoids any explicit loops. JavaScript handles everything:
function flatten(arr) {
return [].concat(...arr);
}
console.log(flatten([['foo', 'bar'], ['baz', 'qux']]));
// -> ["foo", "bar", "baz", "qux"]
console.log(flatten([[1], [2], 3, 4, [5]]));
// -> [1, 2, 3, 4, 5]
console.log(flatten([false, [true, [false]], [true]]));
// -> [false, true, [false], true]
console.log(flatten([]));
// -> []
Upvotes: 5
Reputation: 83
Following could be used as a general implementation of Array.prototype.flat()
function flattenArray(arr, depth = 1) {
if (!Array.isArray(arr)) {
return [arr];
}
return depth > 0
? arr.reduce(
(acc, curr) =>
acc.concat(
Array.isArray(curr) ? flattenArray(curr, depth - 1) : curr
),
[]
)
: arr.slice();
}
const a = [1, 2, 3, 4];
const b = "a";
const c = [1, [2, 3], 4];
const d = [1, [2, [3, 4], 5], 6];
const e = [1, [2, [3, [4, [5], [6]], 7], 8], 9];
console.log(flattenArray(a, Infinity));
console.log(flattenArray(b, Infinity));
console.log(flattenArray(c, Infinity));
console.log(flattenArray(d, Infinity));
console.log(flattenArray(e, Infinity));
Upvotes: 0
Reputation: 21
You can use this to forget about the depth of nesting:
let multiArr = [1, [1, 2, [3, 4]], [2, 4, [45, 98]]];
while (multiArr.find((elem) => Array.isArray(elem))) {
multiArr = [].concat.apply([], multiArr);
}
console.log(multiArr);
Upvotes: -1
Reputation: 5547
A possible alternative would be without using flat():
var arr = [['object1', 'object2'],['object1'],['object1','object2','object3']];
var flattened = [].concat.apply([],arr);
Upvotes: -1
Reputation: 14904
Well you can use spread operator with reduce.
function flatten(array) {
return array.reduce((a,v) => [...a, ...(Array.isArray(v) ? v : [v])], []);
}
console.log(flatten([['foo', 'bar'], 'baz', 'qux']))
Upvotes: 0
Reputation: 12209
You had a typo where in your innermost loop you set i to 0 instead of j. The only other thing you needed to do was check to see if each element in the outer array was scalar (not an array) and push it to the returned array if so.
function flatten(arr) {
let flat = []
for (let i=0; i < arr.length; i++) {
const cur = arr[i]
if(!Array.isArray(cur)){
flat.push(cur)
}else{
for (let j=0; j < cur.length; j++) {
flat.push(cur[j])
}
}
}
return flat
}
console.log(flatten([['foo','bar'],['baz','qux']]))
console.log(flatten([[1],[2],3,4,[5]]))
console.log(flatten([false,[true,[false]],[true]]))
console.log(flatten([]))
Upvotes: 0
Reputation: 386570
You have an error here:
for (let j = 0; i < current.length; j++) {
// ^ wrong variable, should be j
And you need to check if the value is not an array, then just push the current value and continue the loop.
function flatten(array) {
let flattened = [];
for (let i = 0; i < array.length; i++) {
const current = array[i];
if (!Array.isArray(current)) {
flattened.push(current);
continue;
}
for (let j = 0; j < current.length; j++) {
flattened.push(current[j])
}
}
return flattened
}
console.log(flatten([['foo', 'bar'], ['baz', 'qux']]));
// -> ["foo", "bar", "baz", "qux"]
console.log(flatten([[1], [2], 3, 4, [5]]));
// -> [1, 2, 3, 4, 5]
console.log(flatten([false, [true, [false]], [true]]));
// -> [false, true, [false], true]
console.log(flatten([]));
// -> []
Upvotes: 0
Reputation: 78
you can use the reducer of javascript as an alternative to flat().
const arr = [1, 2, [3, 4]];
arr.reduce((acc, val) => acc.concat(val), []);
// [1, 2, 3, 4]
or you can use decomposition syntax
const flattened = arr => [].concat(...arr);
For more details, go to Mozilla MDN
Upvotes: 1
Reputation: 4425
You could use Array.reduce
and the spread syntax
:
function flatten(array) {
return array.reduce(
(accumulator, item) => {
// if `item` is an `array`,
// use the `spread syntax` to
// append items of the array into
// the `accumulator` array
if (Array.isArray(item)) {
return [...accumulator, ...item];
}
// otherwise, return items in the
// accumulator plus the new item
return [...accumulator, item];
}
, []); // initial value of `accumulator`
}
console.log(flatten([['foo', 'bar'], ['baz', 'qux']]));
// -> ["foo", "bar", "baz", "qux"]
console.log(flatten([[1], [2], 3, 4, [5]]));
// -> [1, 2, 3, 4, 5]
console.log(flatten([false, [true, [false]], [true]]));
// -> [false, true, [false], true]
console.log(flatten([]));
// -> []
References:
Upvotes: 3
Reputation: 4562
I hope this helps
var twoDimension = [[1], [2], 3, 4, [5]];
var plano = twoDimension.reduce((acc, el) => acc.concat(el), []);
console.log(plano);
Upvotes: 6