flatten an array without using .flat();

Viewed 4639

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

13 Answers

I hope this helps

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

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

console.log(plano);

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:

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

arr.toString().split(',');

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

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']))

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([]));
// -> []

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([]))

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

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([]));
// -> []

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, ' ') + ']'))

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.

A possible alternative would be without using flat():

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

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

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