locutus
Version:
Locutus other languages' standard libraries to JavaScript for fun and educational purposes
41 lines (40 loc) • 1.6 kB
JavaScript
export function chunk_every(values, count, step = count, leftover = []) {
// discuss at: https://locutus.io/elixir/chunk_every/
// parity verified: Elixir 1.18
// original by: Kevin van Zonneveld (https://kvz.io)
// note 1: Mirrors Elixir Enum.chunk_every/4 semantics with count, step and optional leftover padding.
// example 1: chunk_every([1, 2, 3, 4, 5], 2)
// returns 1: [[1, 2], [3, 4], [5]]
// example 2: chunk_every([1, 2, 3, 4, 5], 2, 2, [])
// returns 2: [[1, 2], [3, 4], [5]]
// example 3: chunk_every([1, 2, 3, 4, 5], 3, 3, [0, 0])
// returns 3: [[1, 2, 3], [4, 5, 0]]
if (!Array.isArray(values)) {
return [];
}
const width = Math.trunc(Number(count));
const stride = Math.trunc(Number(step));
if (!Number.isFinite(width) || width <= 0) {
throw new RangeError('chunk_every(): count must be a positive integer');
}
if (!Number.isFinite(stride) || stride <= 0) {
throw new RangeError('chunk_every(): step must be a positive integer');
}
const pad = Array.isArray(leftover) ? leftover : [];
const out = [];
for (let i = 0; i < values.length; i += stride) {
const chunk = values.slice(i, i + width);
if (chunk.length === width) {
out.push(chunk);
continue;
}
if (chunk.length === 0) {
continue;
}
const padded = [...chunk, ...pad].slice(0, width);
if (padded.length > 0) {
out.push(padded);
}
}
return out;
}