给定一个列表,如何将其拆分为 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)
即,我想保留所有元素
您可以考虑使用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]]