将数组分成相等的部分

时间:2019-03-21 20:10:44

标签: javascript arrays algorithm chunks

我正在寻找一种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]]

因此,基本上,输出分布在多个数组中,其中最大元素数作为第二个参数传入。

2 个答案:

答案 0 :(得分:4)

您应该重新计算大小,该大小可能需要小于给定的大小。然后从中计算出其余块的大小应减小一小。

因此,您可能会有两个不同的块大小(相差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>

答案 1 :(得分:0)

这是在没有 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));