In Elixir, how can a range be converted to a list?
ElixirElixir Problem Overview
I can declare a range as follows:
range = 1..10
Is there a way to convert the range to a list?
Elixir Solutions
Solution 1 - Elixir
Enum.to_list/1
is what you're looking for:
iex(3)> Enum.to_list 1..10
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Solution 2 - Elixir
The generic way to convert an enumerable into a specific collectable is Enum.into
:
Enum.into 1..10, []
#=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
You can also pass a transformation function as third argument:
Enum.into 1..10, %{}, &({&1, &1})
#=> %{1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9, 10 => 10}
Solution 3 - Elixir
Use Enum.map/2
range = 1..10
Enum.map(range, fn(x) -> x end)
or
Enum.map(range, &(&1))
Solution 4 - Elixir
Use the pipeline operator
1..10 |> Enum.to_list
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
and then you can apply further transformations on it like
1..10 |> Enum.to_list |> Enum.sum
55
Solution 5 - Elixir
Here's a Benchfella microbenchmark comparing the approaches found in the previous answers.
defmodule RangeToListBench do
use Benchfella
@test_range 1..1000
bench "Enum.map", do: Enum.map(@test_range, &(&1))
bench "Enum.to_list", do: Enum.to_list(@test_range)
bench "Enum.into", do: Enum.into(@test_range, [])
end
Here's what I get on my 2017 MacBook Pro with @test_range
set to 1..1000
:
benchmark nam iterations average time
Enum.to_list 100000 21.97 µs/op
Enum.into 100000 23.72 µs/op
Enum.map 50000 34.72 µs/op
With a much larger range of 1..100_000
, the relative ordering stays the same:
Enum.to_list 1000 2427.21 µs/op
Enum.into 1000 2540.62 µs/op
Enum.map 500 3414.07 µs/op
The same goes for a much smaller range of 1..10
:
Enum.to_list 10000000 0.32 µs/op
Enum.into 10000000 0.32 µs/op
Enum.map 10000000 0.45 µs/op
TL;DR: Enum.to_list/1
is probably the most efficient choice.