将列表拆分为 N 个部分

Iva*_*ari 4 elixir

给定一个列表,如何将其拆分为 N 个子列表?它们不一定必须具有相同的大小。例如,给定 9 个元素并将其拆分为 N = 3 个子列表 => 3x3。或进入 N = 4 个子列表 => 2、2、2 和 1。

我怎样才能做到这一点?Elixir 库里没有函数吗?

Enum.split 将列表分成两部分

更新:

如果我有 7 个元素并且我想将它们分成 3 个子列表,则应该创建 3 个子列表:

[[3 elements], [2 elements], [2 elements]] 
Run Code Online (Sandbox Code Playgroud)

即,我想保留所有元素

Kev*_*son 7

您可以考虑使用Enum.chunk_every将列表拆分为每个包含 n 个元素的子列表:

some_list = [1, 2, 3, 4, 5, 6]
Enum.chunk_every(some_list, 2)
[[1, 2], [3, 4], [5, 6]]
Run Code Online (Sandbox Code Playgroud)

首先通过计算列表的总长度:

total_length = length(some_list)
Run Code Online (Sandbox Code Playgroud)

并将该数字除以所需的部分数量,从而得出每个块的长度:

desired_amount_of_sublists = 3
chunk_length = Integer.floor_div(total_length, desired_amount_of_sublists)
Run Code Online (Sandbox Code Playgroud)

应该允许您随意将列表分成您需要的多个部分:

Enum.chunk_every(some_list, chunk_length)
[[1, 2], [3, 4], [5, 6]]
Run Code Online (Sandbox Code Playgroud)

如果您严格要求每个子列表恰好包含 n 个元素,那么您可以传入选项:discard以在最后一个子列表少于 n 个元素时丢弃它:

Enum.chunk_every([1,2,3,4,5,6,7], 2, 2, :discard)
[[1, 2], [3, 4], [5, 6]]
Run Code Online (Sandbox Code Playgroud)

如果您有不能丢弃任何元素的硬性要求,例如您需要将其余元素与第一个子列表合并,那么您可以执行以下操作:

说上面的你到达:

result_so_far = Enum.chunk_every([1,2,3,4,5,6,7], 2)
[[1, 2], [3, 4], [5, 6], [7]]
Run Code Online (Sandbox Code Playgroud)

首先反转result_so_far,并取其第一个子列表,即[7],如下所示:

[last_sublist | other_sublists] = Enum.reverse(result_so_far)

然后你检查last_sublist. 如果它对应于chunk_length,那么你很好,result_so_far有想要的结果。在它小于 的情况下chunk_length,您需要将其元素与 的第一个子列表合并result_so_far,您可以执行以下操作: [first_sublist | rest ] = Enum.reverse(other_sublists)

[Enum.concat(first_sublist, last_sublist) | rest] 然后应该渲染

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