I cannot figure out the best way to dynamically generate a multidimensional array with 2 different sizes.
We have a UI that requires a row of 4 items, then 3. This pattern would repeat until the content in the array has been spent.
This is essentially what I need to do:
// Convert
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
// to
const rows [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10, 11], [12, 13, 14]];
This is what I currently have, it is only converting the arrays to 4 each.
const buildRows = (arr, length) => arr.reduce((rows, val, i) => (
i % length == 0 ? rows.push([val]) : rows[rows.length-1].push(val)
) && rows, []);
Thank you in advance for the help.
To declare a 2D array, specify the type of elements that will be stored in the array, then ( [][] ) to show that it is a 2D array of that type, then at least one space, and then a name for the array. Note that the declarations below just name the variable and say what type of array it will reference.
You can even create a two-dimensional array where each subarray has a different length or different type, also known as a heterogeneous array in Java. This means it's possible to create a two-dimensional array with variable column length in Java.
Technically, there is no two-dimensional array in JavaScript. JavaScript supports 2D arrays through jagged arrays – an array of arrays.
The following solution will mutate (empty) the input array array
:
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
let result = [], i = 0;
while(array.length) { // while there still items in array (array is continually getting shrunk untill it is emptied (array.length === 0))
result.push(array.splice(0, i++ % 2? 3: 4)); // cut the first 3 or 4 numbers depending on the index of the cut i (if i is pair, then cut 4, else, cut 3) and then push the cut-out items into the result array
}
console.log(result);
If you don't want to mutate it, then use slice
instead of splice
, but you'll have to provide the start index of the cut:
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
let result = [], i = 0, next = 0; // next will be the index from which the cut will start
while(next < array.length) { // there is still items to cut
let itemsToCut = i % 2? 3: 4; // determine how many items we are going to cut
result.push(array.slice(next, next + itemsToCut)); // cut the items between next and next + itemsToCut
next += itemsToCut; // increment next by the number of cut-out items so it will point to the next item
i++;
}
console.log(result);
I suggest a more self-documenting generator solution where even & odd row-sizes are not hardcoded but supplied via arguments:
function* reshape(array, ...rows) {
let i = 0;
while (true) for (let row of rows) {
if (i >= array.length) return;
yield array.slice(i, i += row);
}
}
// Example:
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
for (let row of reshape(array, 4, 3)) console.log(row);
A true generator purist would simplify reshape
by first introducing a repeat
generator:
function* repeat(iterable) {
while (true) yield* iterable;
}
function* reshape(array, ...rows) {
let i = 0;
for (let row of repeat(rows)) {
if (i >= array.length) break;
yield array.slice(i, i += row);
}
}
// Example:
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
for (let row of reshape(array, 4, 3)) console.log(row);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With