Можно использовать Enum.chunk_every
, чтобы разбить список на подсписки из n элементов суммы каждый:
some_list = [1, 2, 3, 4, 5, 6]
Enum.chunk_every(some_list, 2)
[[1, 2], [3, 4], [5, 6]]
Путем вычисления общей длины списка сначала:
total_length = length(some_list)
и деление этого числа на желаемое количество частей, дающее вам длину каждого блока:
desired_amount_of_sublists = 3
chunk_length = Integer.floor_div(total_length, desired_amount_of_sublists)
должно позволить вам произвольно разделить список на столько частей, сколько вам нужно:
Enum.chunk_every(some_list, chunk_length)
[[1, 2], [3, 4], [5, 6]]
В случае, если у вас есть жесткое требование, чтобы каждый подсписок состоял ровно из n элементов, вы можете передать опцию :discard
, чтобы отменить последний подсписок, если он меньше чем n элементов:
Enum.chunk_every([1,2,3,4,5,6,7], 2, 2, :discard)
[[1, 2], [3, 4], [5, 6]]
В случае, если у вас есть жесткое требование, когда вы не можете отказаться от какого-либо элемента, и, например, вам нужно, чтобы остальные элементы были включены в первый подсписок, вы можете сделать следующее:
Скажите, что с вышеприведенным вы получите:
result_so_far = Enum.chunk_every([1,2,3,4,5,6,7], 2)
[[1, 2], [3, 4], [5, 6], [7]]
Первый обратный 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]]