Home > OS >  How to create a new 2D array out of each depths from a given nested array?
How to create a new 2D array out of each depths from a given nested array?

Time:10-19

Input:

[1,2,[3,4,[5,6]]]

Output:

[[1,2],[3,4],[5,6]]

Here is the solution:

function convert(a,res=[]) {
  const group = (arr) => {
    res.push(arr.slice(0,2));
    arr.map((v) => Array.isArray(v) && group(v));
  }
  group(a);
  return res;
}

console.log(convert([1,2,[3,4]])); // [[1,2],[3,4]]
console.log(convert([1,2,[3,4,[5,6]]])); // [[1,2],[3,4],[5,6]]
console.log(convert([1,2,[3,4,[5,6,[7,8]]]])); // [[1,2],[3,4],[5,6],[7,8]];

Although the problem is solved, For learning purposes, I've always wonder how to solve this without the nesting function approach. I've tried to refactor the code as followed:

function convert(a,i=0,res=[]) {
  return i >= a.length
    ? res
    : convert(
      a,
      i 1,
      Array.isArray(a[i]) ? [...res,a.slice(0,2)] : res
    )
}

console.log(convert([1,2,[3,4]])); // [[1,2]]
console.log(convert([1,2,[3,4,[5,6]]])); // [[1,2]]
console.log(convert([1,2,[3,4,[5,6,[7,8]]]])); // [[1,2]]

As you can see, the result is less than ideal. I just couldn't quite wrap my head around it. Any feedback and pointer will be greatly appreciated :)

UPDATE:

Here is the solution which covers even more test cases:

function convert(a,res=[]) {
  return !a.length
    ? res
    : convert(
      a.filter(Array.isArray).flat(),
      [...res,a.filter((v) => !Array.isArray(v))]
    );
}

console.log(convert([1,2,[3,4]])); // [[1,2],[3,4]]
console.log(convert([1,2,[3,4,[5,6]]])); // [[1,2],[3,4],[5,6]]
console.log(convert([1,2,[3,4,[5,6,[7,8]]]])); // [[1,2],[3,4],[5,6],[7,8]];
console.log(convert([1,2,[5,6,[9,10],7,8],3,4])); // [[1,2,3,4],[5,6,7,8],[9,10]]
console.log(convert([1,5,5,[5,[1,2,1,1],5,5],5,[5]])); // [[1,5,5,5],[5,5,5,5],[1,2,1,1]]
console.log(convert([1,[2],1,[[2]],1,[[[2]]],1,[[[[2]]]]])); // [[1,1,1,1],[2],[2],[2],[2]]

CodePudding user response:

I'm not sure if this is what you mean, but you can use a straight recursive call, spreading each result into the previous.

const input = [1, 2, [3, 4, [5, 6]]];

function flatten(arr) {
  const res = [[]];
  for (const e of arr) {
    Array.isArray(e) ? res.push(...flatten(e)) : res[0].push(e);
  }

  return res;
}

console.log(flatten(input));

This works even if the elements on any level are split by nested levels, and for variable numbers of elements on any given level.

const input = [1, 2, [4, [5, 6, [8, 9], 7]], 3]; 
// [[ 1, 2, 3 ], [ 4 ], [ 5, 6, 7 ], [ 8, 9 ]]

function flatten(arr) {
  const res = [[]];
  for (const e of arr) {
    Array.isArray(e) ? res.push(...flatten(e)) : res[0].push(e);
  }

  return res;
}

console.log(flatten(input));

  • Related