将列表分成两半(±1)

问题描述 投票:0回答:4

我知道我可以通过这样做将 even 列表分成相等的两半在长生不老药中:

list = [1, 2, 3, 4, 5, 6]
len = round(length(list) / 2)

[a, b] = Enum.chunk(list, len)            # => [[1, 2, 3], [4, 5, 6]]

但是是否有内置的 ruby-esque 方法或一些更有效的方法来处理奇数长度列表?

elixir
4个回答
10
投票

Enum.chunk 实际上需要 4 个参数,如果包含第 4 个 (

pad
) 参数,它将使用奇数长度列表:

iex(14)> Enum.chunk([1,2,3,4,5], 3, 3, [])
[[1, 2, 3], [4, 5]]

5
投票

在浏览文档并在其他地方搜索后,我仍然没有找到内置的解决方案,但我确实遇到了

Enum.split/2
。此方法似乎更适合划分奇数长度列表,但返回
tuple
而不是列表列表。

我仍然不知道这有多有效。

例子:

def split(list) do
  len = round(length(list)/2)
  Enum.split(list, len)
end


split([1, 2, 3, 4])        # => {[1, 2], [3, 4]}
split([5, 6, 7, 8, 9])     # => {[5, 6, 7], [8, 9]}

2
投票

我不相信有任何“更惯用”的方式来做到这一点。我不知道有内置方法可以做到这一点。

一个建议——如果你正在处理更大的列表,你最好使用流而不是枚举。

list = [1,2,3,4,5,6,7,8,9]
s = Stream.take_every(list,2)
l2 = Enum.to_list(s)  #=> [1,3,5,7,9]

然后

l1 = list -- l2 #=> [2,4,6,8]

您最好尽可能使用 Stream,因为 Stream 是惰性求值的。在这种特殊情况下,它不会有所作为。但在某些情况下,惰性评估确实可以加快速度。

正如我所说,我的代码并不比您的解决方案更惯用,而且它肯定不是内置函数。


0
投票
Enum.chunk_every(list, Enum.count(list) |> div(2))

list |> then(&(Enum.chunk_every(&1, Enum.count(&1) |> div(2))))
© www.soinside.com 2019 - 2024. All rights reserved.