Reputation: 75740
I know I can split an even list in two equal halves in elixir by doing this:
list = [1, 2, 3, 4, 5, 6]
len = round(length(list) / 2)
[a, b] = Enum.chunk(list, len) # => [[1, 2, 3], [4, 5, 6]]
but is there a ruby-esque method built-in or some more efficient way of doing this that also handles odd-length lists?
Upvotes: 8
Views: 5578
Reputation: 75740
After going through the docs, and searching elsewhere I still didn't find a built in solution, but I did come across Enum.split/2
. This method seems like a better fit to divide odd-length lists but returns a tuple
instead of a list of lists.
I still don't know how efficient this is.
Example:
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]}
Upvotes: 5
Reputation: 84140
Enum.chunk_every/4 actually takes 4 arguments and will work with an odd length list if you include the 4th (pad
) argument:
iex(14)> Enum.chunk_every([1,2,3,4,5], 3, 3, [])
[[1, 2, 3], [4, 5]]
Upvotes: 10
Reputation: 15293
I don't believe there is any "more idiomatic" way to do this. I don't know of a built-in method to do this.
One suggestion--if you're dealing with larger lists, you may be better off to use a Stream rather than an Enum.
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]
And then
l1 = list -- l2 #=> [2,4,6,8]
You're better off to use a Stream where you can because a Stream is lazily evaluated. In this particular case, it wouldn't make a difference. But in some cases lazy evaluation can really speed things up.
As I say my code is no more idiomatic than your solution and it's certainly not a built-in function.
Upvotes: 2