這可能是一個微不足道的問題,但我無法繞開它。如何在Elixir中獲得一個範圍的尾巴
我只是想模式匹配的範圍,獲得頭部和尾部。
這裏是我的嘗試:
iex(1)> [h|t] = [1..3]
[1..3]
iex(2)> h
1..3
iex(3)> t
[]
正如你所看到的,它不會做什麼我的預期。我的期望是h = 1
和t = [2,3]
。
我該如何獲得一個範圍內的頭部和尾部?這甚至可能嗎?
這可能是一個微不足道的問題,但我無法繞開它。如何在Elixir中獲得一個範圍的尾巴
我只是想模式匹配的範圍,獲得頭部和尾部。
這裏是我的嘗試:
iex(1)> [h|t] = [1..3]
[1..3]
iex(2)> h
1..3
iex(3)> t
[]
正如你所看到的,它不會做什麼我的預期。我的期望是h = 1
和t = [2,3]
。
我該如何獲得一個範圍內的頭部和尾部?這甚至可能嗎?
首先,[1..3]
是一個包含1範圍,而不是範圍的列表。其次,範圍本身不是一個列表,它只是一個包含2個值的結構:第一個和最後一個值(Map.from_struct(1..10) #=> %{first: 1, last: 10}
)。如果你想有一個範圍內列表的頭部和尾部,你需要的範圍內轉換到一個列表第一:
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]
注意,這是非常低效的取決於你在做什麼。一個範圍佔用很少的內存(一個Struct + 2個整數鍵)。列表將佔據與列表中項目數量成比例的空間。取決於你在做什麼,可能比將範圍轉換爲列表更好。
最有效的方法可能是隻是抓住它從底層AST:
iex(6)> Macro.escape(1..10)
{:%{}, [], [__struct__: Range, first: 1, last: 10]}
因此...
{:%{}, [], [__struct__: Range, first: head, last: tail]} = Macro.escape(range)
iex(10)> head
1
iex(11)> tail
10
編輯:使用quote
但Macro.escape
似乎是這裏更強大
你可以通過它的inde X
iex(1)> range = 1..3
1..3
iex(2)> last_index = Enum.count(range) - 1
2
iex(3)> Enum.at(range, last_index)
3
這應該更好地工作
iex(42)> range = 1..100
1..100
iex(43)> _..last = range
1..100
iex(44)> last
100
很不錯的!我不知道你可以這樣做。 +1 – Simone