将数组分成相等的部分
Splitting an array in equal parts
我正在寻找一种 Javascript 算法来将数组拆分成块,但要避免任何小的遗留问题。例如:
_.chunk([1, 2, 3, 4, 5, 6, 7], 3) // [[1, 2, 3], [4, 5, 6], [7]]
但我想要这个:
_.chunk([1, 2, 3, 4, 5, 6, 7], 3) // [[1, 2, 3], [4, 5], [6, 7]]
_.chunk([1, 2, 3, 4, 5, 6, 7], 4) // [[1, 2, 3, 4], [5, 6, 7]]
_.chunk([1, 2, 3, 4, 5, 6, 7], 5) // [[1, 2, 3, 4], [5, 6, 7]]
_.chunk([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3) // [[1, 2, 3], [4, 5, 6], [7, 8], [9, 10]]
所以基本上输出分布在几个数组中,最大数量的元素作为第二个参数传入。
您应该重新计算大小,可能需要比给定的小一些。然后计算剩余块的大小应减一的位置。
所以你可能有两个不同的块大小(相差 1)。对于两者,您都可以调用原始 _.chunk
:
function chunk(arr, size) {
const count = Math.ceil(arr.length / size);
size = Math.ceil(arr.length / count);
const i = arr.length-(size-1)*(arr.length%size && size-(arr.length%size));
return _.chunk(arr.slice(0, i), size).concat(
_.chunk(arr.slice(i), size-1));
}
for (let i = 1; i < 9; i++) {
console.log(i, JSON.stringify(chunk([1, 2, 3, 4, 5, 6, 7], i)));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script>
这是在没有 lodash 的情况下完成的,它生成一个适当长度的数组,然后用输入数组的切片填充部分。就几行代码,看你怎么算。
需要注意的是切片取决于小数点的舍入方式。对于最后一个示例,您想要分块一个 10 长度的数组,每个块限制为 3 个。好吧,把它分开,你会得到输出:
[ [1,2], [3,4,5], [6,7], [8,9,10] ]
而不是你想要的:
[ [1,2,3], [4,5,6], [7,8], [9,10] ]
对于大多数应用程序,我认为这并不重要。我正在使用它来将大量输入分块到一个被节流的 API。
function chunk(array, limit) {
const numChunks = Math.ceil(array.length / limit);
return Array.from(
{ length: numChunks },
(_, i) => array.slice(i * array.length / numChunks, (i + 1) * array.length / numChunks)
);
}
console.log(chunk([1, 2, 3, 4, 5, 6, 7], 3));
console.log(chunk([1, 2, 3, 4, 5, 6, 7], 4));
console.log(chunk([1, 2, 3, 4, 5, 6, 7], 5));
console.log(chunk([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3));
另一种解决方案使用递归来分块“剩余”数组。这个符合您的标准。
function chunk(array, limit) {
if (array.length <= limit) return [array];
const perChunk = Math.ceil(array.length / Math.ceil(array.length / limit));
return [array.slice(0, perChunk)].concat(chunk(array.slice(perChunk), limit));
}
console.log(chunk([1, 2, 3, 4, 5, 6, 7], 3));
console.log(chunk([1, 2, 3, 4, 5, 6, 7], 4));
console.log(chunk([1, 2, 3, 4, 5, 6, 7], 5));
console.log(chunk([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3));
我正在寻找一种 Javascript 算法来将数组拆分成块,但要避免任何小的遗留问题。例如:
_.chunk([1, 2, 3, 4, 5, 6, 7], 3) // [[1, 2, 3], [4, 5, 6], [7]]
但我想要这个:
_.chunk([1, 2, 3, 4, 5, 6, 7], 3) // [[1, 2, 3], [4, 5], [6, 7]]
_.chunk([1, 2, 3, 4, 5, 6, 7], 4) // [[1, 2, 3, 4], [5, 6, 7]]
_.chunk([1, 2, 3, 4, 5, 6, 7], 5) // [[1, 2, 3, 4], [5, 6, 7]]
_.chunk([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3) // [[1, 2, 3], [4, 5, 6], [7, 8], [9, 10]]
所以基本上输出分布在几个数组中,最大数量的元素作为第二个参数传入。
您应该重新计算大小,可能需要比给定的小一些。然后计算剩余块的大小应减一的位置。
所以你可能有两个不同的块大小(相差 1)。对于两者,您都可以调用原始 _.chunk
:
function chunk(arr, size) {
const count = Math.ceil(arr.length / size);
size = Math.ceil(arr.length / count);
const i = arr.length-(size-1)*(arr.length%size && size-(arr.length%size));
return _.chunk(arr.slice(0, i), size).concat(
_.chunk(arr.slice(i), size-1));
}
for (let i = 1; i < 9; i++) {
console.log(i, JSON.stringify(chunk([1, 2, 3, 4, 5, 6, 7], i)));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script>
这是在没有 lodash 的情况下完成的,它生成一个适当长度的数组,然后用输入数组的切片填充部分。就几行代码,看你怎么算。
需要注意的是切片取决于小数点的舍入方式。对于最后一个示例,您想要分块一个 10 长度的数组,每个块限制为 3 个。好吧,把它分开,你会得到输出:
[ [1,2], [3,4,5], [6,7], [8,9,10] ]
而不是你想要的:
[ [1,2,3], [4,5,6], [7,8], [9,10] ]
对于大多数应用程序,我认为这并不重要。我正在使用它来将大量输入分块到一个被节流的 API。
function chunk(array, limit) {
const numChunks = Math.ceil(array.length / limit);
return Array.from(
{ length: numChunks },
(_, i) => array.slice(i * array.length / numChunks, (i + 1) * array.length / numChunks)
);
}
console.log(chunk([1, 2, 3, 4, 5, 6, 7], 3));
console.log(chunk([1, 2, 3, 4, 5, 6, 7], 4));
console.log(chunk([1, 2, 3, 4, 5, 6, 7], 5));
console.log(chunk([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3));
另一种解决方案使用递归来分块“剩余”数组。这个符合您的标准。
function chunk(array, limit) {
if (array.length <= limit) return [array];
const perChunk = Math.ceil(array.length / Math.ceil(array.length / limit));
return [array.slice(0, perChunk)].concat(chunk(array.slice(perChunk), limit));
}
console.log(chunk([1, 2, 3, 4, 5, 6, 7], 3));
console.log(chunk([1, 2, 3, 4, 5, 6, 7], 4));
console.log(chunk([1, 2, 3, 4, 5, 6, 7], 5));
console.log(chunk([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3));