6

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

tryingToBeBetter
  • 365
  • 1
  • 6
  • 16
  • 1
    `for (let j = 0; i < current.length; j++) {` here you have an infinite loop. if `i < current.length` is true, It won't ever change (inside that loop). so the inner loop is doing `flattened.push(current[j])` untill something crashes. – Thomas Jul 05 '20 at 18:48
  • ... personal opinion ... in terms of simplicity, readability and thus, beauty, only approaches that read like that ... `... .reduce((acc, el) => acc.concat(el), [])` ... should be candidates for the accepted answer. – Peter Seliger Jul 05 '20 at 19:02
  • Does this answer your question? [Merge/flatten an array of arrays](https://stackoverflow.com/questions/10865025/merge-flatten-an-array-of-arrays) (check out the non-accepted answers) – SuperStormer Oct 09 '22 at 10:13

18 Answers18

5

I hope this helps

var twoDimension = [[1], [2], 3, 4, [5]];

var plano = twoDimension.reduce((acc, el) => acc.concat(el), []);

console.log(plano);
sonEtLumiere
  • 4,461
  • 3
  • 8
  • 35
3

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:

goto
  • 4,336
  • 15
  • 20
  • what does if (Array.isArray(item)) mean? – tryingToBeBetter Jul 05 '20 at 18:45
  • 1
    @americanguy93 I added comments with explanations, but this basically checks if the item in the array is another array, and if so, it takes it's items and combines it with the final array – goto Jul 05 '20 at 18:48
3

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([]));
// -> []
VLAZ
  • 26,331
  • 9
  • 49
  • 67
2

You can use the following method if your array have primitive data type and want to flat it completely:

arr.toString().split(',');
Mahipal
  • 344
  • 2
  • 13
1

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

1
//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);
0

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']))
bill.gates
  • 14,145
  • 3
  • 19
  • 47
0

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([]));
// -> []
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

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([]))
symlink
  • 11,984
  • 7
  • 29
  • 50
0

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));
0

There is another interesting way to do it.

  1. Stringify the array
  2. remove all array start symbol ([) and array end symbol(])
  3. Add array start symbol at the beginning and array end symbol at the end.
  4. Now parse the resulting string

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, ' ') + ']'))
Ali
  • 1,857
  • 24
  • 25
0

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.

ArifMustafa
  • 4,617
  • 5
  • 40
  • 48
0
var multiDimensionArray = [["a"],["b","c"],["d"]]; //array of arrays
var flatArray = Array.prototype.concat.apply([], multiDimensionArray); //flatten array of arrays
console.log(flatArray); 
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
  • Hello, please see https://meta.stackoverflow.com/editing-help Thanks! – Eric Aya Oct 27 '22 at 14:29
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 31 '22 at 06:58
  • While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. You can find more information on how to write good answers in the help center: https://stackoverflow.com/help/how-to-answer . Good luck – nima Nov 01 '22 at 07:53
  • That's just [this answer](https://stackoverflow.com/a/62750495/), isn't it? – General Grievance Nov 01 '22 at 12:47
0

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;
}

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – 3ddavies Jan 15 '23 at 05:38
0
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);
moken
  • 3,227
  • 8
  • 13
  • 23
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 06 '23 at 10:37
0
//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)) 
  • 1
    Answer needs supporting information Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](https://stackoverflow.com/help/how-to-answer). – moken Jul 25 '23 at 12:25
-1

A possible alternative would be without using flat():

var arr = [['object1', 'object2'],['object1'],['object1','object2','object3']];

var flattened = [].concat.apply([],arr);

Mohsen Alyafei
  • 4,765
  • 3
  • 30
  • 42
-1

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);