Split Array into Chunks

Split array into chunks

The array.slice() method can extract a slice from the beginning, middle, or end of an array for whatever purposes you require, without changing the original array.

const chunkSize = 10;
for (let i = 0; i < array.length; i += chunkSize) {
const chunk = array.slice(i, i + chunkSize);
// do whatever
}

The last chunk may be smaller than chunkSize. For example when given an array of 12 elements the first chunk will have 10 elements, the second chunk only has 2.

Note that a chunkSize of 0 will cause an infinite loop.

Can't seem to identify the issue (splitting an array in chunks)

You need an index as second parameter of Array#slice, instead of the length of slice.

For example if you take the second array, index = 2 and the second parameter has to be 4, the index of the end for slicing.

                     chunks
values 1 2 3 4 5 6
indices 0 1 2 3 4 5
slice 0 2 1 2
2 4 3 4
4 6 5 6

function test(arr, num) {
let idx = 0;
let newArr = [];
while (idx < arr.length) {
newArr.push(arr.slice(idx, idx += num));
}
return newArr;
}

let arr = [1, 2, 3, 4, 5, 6];

console.log(test(arr, 2));

Splitting an array into equal chunks and then allot remaining

Use the remainder of the division to get the number of slices that need an extra element. Then use the index in the new (chunked) array to determine whether it needs that extra element (i.e. when that index is less than the remainder).

NB: I would not alter the Array prototype. Just make this a plain function.

Implementation:

function partition(arr, length) {
let rest = arr.length % length;
let size = Math.floor(arr.length / length);
let j = 0;
return Array.from({length}, (_, i) => arr.slice(j, j += size + (i < rest)));
}

let data = Array.from({length: 151}, (_,i) => i+1);
let result = partition(data, 31);
console.log(result);

How to split an array into chunks of a given length in python?

Why don't you try out a list comprehension?

Example:

[ids[i:i+2] for i in range(0,len(ids),2)]

Output:

[[1, 2], [3, 4], [5, 6], [7, 8], [9]]

Split array into different size chunks (4, 3, 3, 3, 4, 3, 3, 3, etc)

You could take two indices, one for the data array and one for sizes. Then slice the array with a given length and push the chunk to the chunks array.

Proceed until end of data.

var data = Array.from({ length: 26 }, (_, i) => i + 1),

sizes = [4, 3, 3, 3],

i = 0,

j = 0,

chunks = [];

while (i < data.length) chunks.push(data.slice(i, i += sizes[j++ % sizes.length]));

console.log(chunks);
.as-console-wrapper { max-height: 100% !important; top: 0; }

How to split an array into interval chunks

You can filter the number from your enum and group consecutive numbers in arrays.

enum MyEnum {
elem1 = 100,
elem2 = 101,
elem3 = 102,
elem4 = 103,

elem5 = 200,
elem6 = 201,
elem7 = 202,

elem8 = 300,
elem9 = 301
}

Object.entries(MyEnum)
.filter(([x]) => !isNaN(parseInt(x)))
.map(([, key]) => MyEnum[key])
.reduce((r, val, i, a) => {
if (!i || val !== a[i - 1] + 1) r.push([]);
r[r.length - 1].push(val);
return r;
}, []);

Break a array into n chunks with overlapping start element

Here is a mapping function that produces the result:

const overlapSplit = (arr, length) => {
let chunk = 1 + Math.max(1, Math.ceil((arr.length - 1) / length));
if (length > 1 && (chunk - 1) * (length - 1) + 1 > arr.length) return overlapSplit(arr, length - 1);
return Array.from({length}, (_, i) =>
arr.slice(i * chunk - i, i * chunk - i + chunk)
);
}

console.log(overlapSplit([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], 6));

Split an array into smaller chunks of arrays with the length provided by size. Need explanation for solution with modulo

Instead of using your (definitely more efficient, and also clearer) approach of taking consecutive slices, this takes the array item by item, storing the next group to be added in a temporary array. The test is basically asking (with a weird negative test) "Is this index not the last one in the group?" If that condition is true, and we're not on the last one for the current group, we simply add to the temporary group. If it's false, and we are on the last one, we add to the temporary group, add the temporary group to our output and create a new temporary group.

With a little refactoring, we can make this cleaner, perhaps something like this:

function chunkArrayInGroups(arr, size) {
const result = []
let temp = []

for (let a = 0; a < arr .length; a ++) {
temp .push (arr [a])
if (a % size === size - 1) {
result .push (temp)
temp = []
}
}

if (temp .length > 0) result .push (temp)

return result
}

But this holds no advantages over your approach, and is definitely less efficient. So I wouldn't consider it.

Here's an alternative that is to my mind cleaner, but also less efficient than yours:

const chunk = (xs, n) => xs .length <= n 
? [[...xs]]
: [xs .slice (0, n)] .concat (chunk (xs .slice (n), n))

This one grabs the first group by slicing it from the beginning of the array, and concatenates the results of recursively calling itself with the remainder of the array. The recursion ends when there are at most n elements remaining, and then we return an array containing only a copy of our input array ([[...x]]). We make the copy because all the other results are copies and not references, and it's better to be consistent.

This is similar to your approach in terms of number of slices and tests, but because of the recursive nature, it will fail for very large arrays and the repeated calls will make it somewhat less efficient. I'm often willing to take that tradeoff for cleaner code, myself, but YMMV.

Split array into chunks of array if it is sequential in javaScript

Not sure this is what you expected but you will get expected output in this way

console.log(chunk([36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72], 4));

function checkSequence(arr) {
for (let i = 1; i < arr.length; i++) {
if (arr[i] - arr[i - 1] > 1) {
return false;
}
}
return true;
}
function chunk(arr, n) {
let i = 0;
var arr1 = [];
while (i < arr.length) {
const res = arr.slice(i, i + n);
if (checkSequence(res) && res.length === 4) {
arr1.push(res);
i = i + n;
} else {
i = i + 1;
}
}
return arr1;
}


Related Topics



Leave a reply



Submit