如何在Elixir中将一个列表拆分为N个子列表?
Splitting a List into N Sublists in Elixir
Great question! Elixir's standard library doesn't have a built-in function that directly splits a list into exactly N sublists with as equal sizes as possible (while retaining all elements), but it's straightforward to implement one using basic Enum and List functions.
Step-by-Step Implementation
Here's a function that does exactly what you need:
defmodule ListSplitter do def split_into_n_sublists(list, n) when n > 0 do list_length = length(list) base_chunk_size = div(list_length, n) remainder = rem(list_length, n) # Create a list of chunk sizes: first `remainder` chunks are 1 element larger chunk_sizes = List.duplicate(base_chunk_size + 1, remainder) ++ List.duplicate(base_chunk_size, n - remainder) # Iterate over chunk sizes to split the original list Enum.reduce(chunk_sizes, {[], list}, fn size, {chunks, remaining} -> {current_chunk, new_remaining} = Enum.split(remaining, size) {chunks ++ [current_chunk], new_remaining} end) |> elem(0) end def split_into_n_sublists(_list, 0) do raise ArgumentError, "Cannot split into 0 sublists" end end
How It Works
Let's break down the logic with your examples:
Calculate Base Size & Remainder:
- For 7 elements split into 3 sublists:
base_chunk_size = 7 // 3 = 2remainder = 7 % 3 = 1
- This means we need 1 chunk of
2 + 1 = 3elements, and3 - 1 = 2chunks of 2 elements.
- For 7 elements split into 3 sublists:
Generate Chunk Sizes:
- The
chunk_sizeslist becomes[3, 2, 2]for the 7-element example.
- The
Split the List:
- We use
Enum.reduceto iterate over each chunk size, splitting the remaining part of the list each time and collecting the chunks.
- We use
Testing the Function
Let's verify with your examples (note: your 9-element into 4 sublists example likely had a typo—2+2+2+1 sums to 7, so the correct split is 3+2+2+2 to retain all 9 elements):
# 9 elements split into 3 sublists ListSplitter.split_into_n_sublists(1..9 |> Enum.to_list(), 3) # Output: [[1,2,3], [4,5,6], [7,8,9]] # 9 elements split into 4 sublists (sum is 9: 3+2+2+2) ListSplitter.split_into_n_sublists(1..9 |> Enum.to_list(), 4) # Output: [[1,2,3], [4,5], [6,7], [8,9]] # 7 elements split into 3 sublists ListSplitter.split_into_n_sublists(1..7 |> Enum.to_list(), 3) # Output: [[1,2,3], [4,5], [6,7]]
Edge Cases
- If
nis larger than the list length: The function will createlist_lengthsublists with 1 element each, andn - list_lengthempty sublists (all elements are retained). - If
nis 0: The function raises an error to avoid invalid input.
内容的提问来源于stack exchange,提问作者Ivanari
相关产品推荐
相关产品推荐

