What is the process for generating a fresh 2D array from each layer within a provided nested array?

Input:

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

Output:

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

Provided below is a solution to the given problem:

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 initial problem is solved using a nested function approach, there's an attempt to refactor the code without it as shown below:

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

However, the result is not as expected. Seeking feedback and pointers for improvement:

UPDATE:

Here is an updated solution that covers 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]]

Answer №1

Perhaps this method aligns with your intentions: employing a direct recursive call, spreading each outcome 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 technique accommodates situations where elements are arranged in nested layers, regardless of the number of elements on each 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));

Edit

To address additional conditions mentioned in the comments, while still utilizing direct recursion without passing an accumulator to subsequent calls, a potential approach could be as follows.

function flatten(arr) {
  const level = [], nested = [];

  for (const e of arr) {
    Array.isArray(e) ? nested.push(...e) : level.push(e);
  }

  return [level, ...(nested.length ? flatten(nested) : [])]
}

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

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

console.log(flatten([1, [2], 1, [[2]], 1, [[[2]]], 1, [[[[2]]]]]));
// [[ 1, 1, 1, 1 ], [ 2 ], [ 2 ], [ 2 ], [ 2 ]]

console.log(flatten([1, 5, 5, [5, [1, 2, 1, 1], 5, 5], 5, [5]]));
// [[ 1, 5, 5, 5 ], [ 5, 5, 5, 5 ], [ 1, 2, 1, 1 ]]

Answer №2

In my opinion, the updated algorithm you have is satisfactory.

However, I believe it could be simplified further by utilizing a reusable utility function. I typically have a function called partition readily available. This function takes a predicate function as input and returns another function that divides an array into two separate sub-arrays based on whether the predicate evaluates to true or false.

By incorporating this utility function, the solution becomes much more straightforward:

const partition = (pred) => (xs) => 
  xs .reduce (([t, f], x) => pred (x) ? [t .concat (x), f]: [t, f .concat (x)], [[], []])

const convert = (xs, [rest, first] = partition (Array .isArray) (xs)) =>
  xs .length == 0 ? [] : [first, ...convert (rest)]

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]]
.as-console-wrapper {max-height: 100% !important; top: 0}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Can we improve the coding of this as it seems inefficient and uses up too much room?

Do you think there is a more efficient way to write this code? It seems quite impractical and takes up a lot of space. Essentially, it's about the random chance of obtaining a rarity, like acquiring an Uncommon sword. if (Math.random() * 100 < 100 ...

Exploring the handling of the nth element within a jQuery each loop

In the process of looping through elements using an each loop, function test(){ $('#first li').each(function(n){$(this).//jQuery effects for nth li of first \\ need to process nth li of id="second" simultaneously }); Is there a wa ...

I'm having trouble getting my HTML POST request form to connect with the Express app.post. Any tips on how to properly pass on numeric variables to a different POST request?

There seems to be a misunderstanding or error on my part regarding POST and GET requests based on what I've read online. On myNumber.ejs, I have a submit form. Upon submission, the view switches to Add.ejs. The goal is for Add.ejs to display both the ...

Sizing labels for responsive bar charts with chart.js

I'm encountering a problem with my bar chart created using chart.js - the responsive feature works well for some elements but not all. Specifically, the labels on my bar chart do not resize along with the window, resulting in a strange look at smaller ...

Instructions for modifying the color of the close button in the angularjs ui-select module

I am currently using ui-select for multiple selection in a dropdown. When an item is selected, it displays a cross button on the upper right corner of the selected item. Is there a way to change the color of the cross button to red? <ui-select multip ...

Encountering a Typescript error when attempting to access the 'submitter' property on type 'Event' in order to retrieve a value in a |REACT| application

I am facing an issue with my React form that contains two submit buttons which need to hit different endpoints using Axios. When I attempt to retrieve the value of the form submitter (to determine which endpoint to target), I encounter an error while work ...

What steps should I take to pinpoint the fundamental mistake in my webpage dedicated to clocks?

Exploring an intriguing clock project that utilizes ancient timekeeping methods found at . Recently encountered a puzzling error in Chrome, where it claims to be unable to call a method on undefined. Strangely enough, the error message is not located near ...

Developing dynamic objects for input string fields in AngularJS

In my AngularJS view, I have the following setup: <label class="control-label">Name:</label> <input type="text" class="form-control" ng-model="config.name" /> <br /> <label class="control-label">versionSpecificApiConfig:&l ...

"Unleashing the power of Asynchronous Ajax Operations

$("#container").on("change", "#control1", function() { if ($("#checkData").val()) { $.get("/Controller/CheckData/" + $("#control2").val(), function(data1) { if(!data1.Success) { alert("Unable to do POST."); ...

Right-align each item when selecting none

Is there a way to change the style of just one of the elements select or option, without affecting the style of both? I attempted to align the select element to the right, while leaving the option elements aligned to the left. However, this did not work a ...

Decoding top-level JSON arrays in Go

Currently, I'm delving into Go by creating a basic http server and I find myself needing to manage JSON responses. When dealing with an object response, handling it idiomatically only requires 2 lines of code: structResult := Foo{} json.Unmar ...

Exploring Objects without the need for loops

Currently, I am focusing on optimizing the performance of the following objects: var scheduleFee = { poor = {level1:25,level2:25,level3:25} , good = {level1:15,level2:20,level3:25} , vgood = {level1:10,le ...

Error encountered: MongoDB failed to execute Javascript as it was unable to save a DBQuery object in the specified location within the collection.js file

When attempting to modify an existing document in a MongoDb collection, an exception is generated with the following message: javascript execution failed : can't save a DBQuery object at src/mongo/shell/collection.js The following actions are perform ...

Tips for sending AngularJS expressions to a controller

I am looking to pass a value from an AngularJS Expression to the controller. Here is the HTML code : <div data-ng-controller="AlbumCtrl"> <div data-ng-repeat="z in songInfo"> <div data-ng-repeat="b in z.album& ...

Discord.js Error: Unable to access undefined properties for 'username'

victim is a variable containing the user's ID input. Despite confirming it as a valid user ID on the server, I encounter the error 'cannot read properties of undefined' This is my first time using client.users.cache.get(victim).username in ...

JavaScript Cookie Array Handling

Is it possible to create a 2D array as a cookie in JavaScript? If so, how can I go about creating this array cookie and looping through it to retrieve data efficiently? Any guidance on this would be greatly appreciated. Thank you! ...

JavaScript code for AES encryption that is compatible with PHP's mcrypt module

Challenge I am faced with the task of encrypting data using Javascript and decrypting it in PHP. I have decided to use Mcrypt in PHP with the AES encryption method, but I am struggling to find a suitable decryption algorithm in Javascript that is compatib ...

Steps for customizing the dropdown arrow background color in react-native-material-dropdown-v2-fixed

Currently, I am utilizing react-native-material-dropdown-v2-fixed and I am looking to modify the background color of the dropdown arrow. Is there a way for me to change its color? It is currently displaying as dark gray. https://i.stack.imgur.com/JKy97.pn ...

Checking for palindromes in a 2D array

I am currently working on a task to determine if a 2D array is a palindrome both row-wise and column-wise using a String or Character variable. I am a bit confused as we are only covering 2D arrays and loops in our lesson, and I keep coming across referenc ...

What is the correct way to utilize href in CSS content property?

Below is the content of a box I have: https://i.sstatic.net/QmG5i.png When the above box is hovered over, it flips to this: https://i.sstatic.net/QsS9t.png This block's HTML code is as follows: <div class='tiles'> <div class= ...