This is probably a trivial question but I can't get my head around it.
I just want to pattern match on a range, getting the head and tail.
Here's what I tried:
iex(1)> [h|t] = [1..3]
[1..3]
iex(2)> h
1..3
iex(3)> t
[]
As you can see, it doesn't do what I expected. My expectation was h = 1
and t = [2,3]
.
How do I get head and tail out of a range? Is that even possible?
First of all, [1..3]
is a list containing 1 range, not a range. Second, a range itself is not a list, it's just a struct containing 2 values: the first and the last value (Map.from_struct(1..10) #=> %{first: 1, last: 10}
). If you want the head and tail of a range as lists, you need to convert the range to a list first:
iex(1)> range = 1..3
1..3
iex(2)> list = Enum.to_list(range)
[1, 2, 3]
iex(3)> [h | t] = list
[1, 2, 3]
iex(4)> h
1
iex(5)> t
[2, 3]
Note that this is very inefficient depending on what you're doing. A range occupies very little memory (a Struct + 2 integer keys). A list will occupy space proportionate to the number of items in the list. Depending on what you're doing, there might be a better way than converting the range to a list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With