【问题标题】:Splitting an array in equal parts将数组分成相等的部分
【发布时间】:2019-03-21 20:10:44
【问题描述】:

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

所以基本上输出分布在几个数组中,最大数量的元素作为第二个参数传入。

【问题讨论】:

  • 小剩菜是什么意思?
  • 那么如果在这个例子中你将 5 作为第二个参数传递呢?还是 6 个?
  • 你能再举一些例子吗? _.chunk([1, 2, 3, 4, 5, 6, 7, 8], 3) 的预期输出是什么
  • "如果 5 或 6 作为第二个参数传入,则两者的预期结果应该是 [[1, 2, 3, 4], [5, 6, 7]]"。这没有任何意义。你能用一些例子更新这个问题吗?
  • @trincot 不过很有趣。他们有 1 个代表。因此,他们无法对帖子发表评论。我假设他们正在发布答案,并且它会自动被添加到评论中。是的,找到了:How did someone with 1 rep post a comment?

标签: javascript arrays algorithm chunks


【解决方案1】:

您应该重新计算大小,它可能需要小于给定的值。然后计算剩余块的大小应该从哪里减一。

因此,您可能会有两种不同的块大小(相差 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)));
}
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"&gt;&lt;/script&gt;

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2015-05-23
      • 2012-11-20
      • 2019-05-06
      • 1970-01-01
      • 2013-07-04
      • 2011-07-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多