tryingToBeBetter
tryingToBeBetter

Reputation: 425

Flatten an array by only one level without using .flat()

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

Answers (20)

Surendhiran Jayaraman
Surendhiran Jayaraman

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

Muzam Ali
Muzam Ali

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

sandeep jadhav
sandeep jadhav

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

user22177121
user22177121

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

Dhyanesh Panchal
Dhyanesh Panchal

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

Ahmad Tahir
Ahmad Tahir

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

SHASHI BHUSHAN
SHASHI BHUSHAN

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

ArifMustafa
ArifMustafa

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

Ali
Ali

Reputation: 1915

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

Upvotes: 0

Mahipal
Mahipal

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

VLAZ
VLAZ

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

Chaitanya Maurya
Chaitanya Maurya

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

Valerii Vitenko
Valerii Vitenko

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

Mohsen Alyafei
Mohsen Alyafei

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

Ilijanovic
Ilijanovic

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

symlink
symlink

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

Nina Scholz
Nina Scholz

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

Shirsha Ghosh
Shirsha Ghosh

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

goto
goto

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

sonEtLumiere
sonEtLumiere

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

Related Questions