我正在尝试编写一个可以将数字列表转换为连续数字列表的函数
例如,转换一个数字列表,如下所示:
[1, 2, 3, 4, 10, 11, 12, 20, 21, 30, 32, 42, 43, 44, 45, 48, 49]
进入连续数字列表,例如:
[[1, 2, 3, 4], [10, 11, 12], [20, 21], [30], [32], [42, 43, 44, 45], [48, 49]]
也许我想得太多了,但我似乎无法在长生不老药中提出一个好的解决方案。
欣赏任何正确方向的建议或指示。谢谢!
我可以看到两种方法:使用Enum.chunk_while
1.5.0 中引入的方法或使用手动递归。
这是一个使用的版本Enum.chunk_while
:
chunk_fun = fn
elem, [] -> {:cont, [elem]}
elem, [prev | _] = acc when prev + 1 == elem -> {:cont, [elem | acc]}
elem, acc -> {:cont, Enum.reverse(acc), [elem]}
end
after_fun = fn
[] -> {:cont, []}
acc -> {:cont, Enum.reverse(acc), []}
end
Enum.chunk_while(list, [], chunk_fun, after_fun)
这是一个手动递归版本:
def chunk_cont([]), do: []
def chunk_cont([elem | list]), do: chunk_cont(list, elem, [])
defp chunk_cont([], elem, acc), do: [Enum.reverse(acc, [elem])]
defp chunk_cont([elem | list], prev, acc) when prev + 1 == elem do
chunk_cont(list, elem, [prev | acc])
end
defp chunk_cont([elem | list], prev, acc) do
[Enum.reverse(acc, [prev]) | chunk_cont(list, elem, [])]
end
两个版本都做了类似的事情。他们遍历列表并将当前元素与前一个元素进行比较。如果当前元素是“下一个”元素,我们将它推到累加器上,如果不是,我们反转并发出累加器,并使用新的累加器继续我们的迭代。一旦完成,我们仍然可以在累加器中留下一些东西,如果是这样,我们会发出最后一个元素。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句