2016-07-31 43 views
0

是否有可能將範圍傳給Elixir的Enum.filter。對於例如如何在Elixir中將範圍傳遞給Enum.filter?

這工作

[1,2,3,4,5] |> Enum.filter(&rem(&1,2)==0) #=> [2,4] 

但這並不

[1..10] |> Enum.filter(&rem(&1,2)==0) #=> bad argument in arithmetic... 

我有一個包含我想傳遞給篩選範圍的列表。例如。

[1..10, 2, 3] 

回答

3

你不需要把它包裝在[]

iex(1)> 1..10 |> Enum.filter(&rem(&1,2)==0) 
[2, 4, 6, 8, 10] 

[1..10]是長度爲1以等於範圍1..10第一元件的列表。如果你想創建可讀性範圍時使用括號,只需使用()

iex(2)> [1..10, 2, 3] |> Enum.flat_map(fn 
...(2)> n when is_number(n) -> if rem(n, 2) == 0, do: [n], else: [] 
...(2)> enum -> Enum.filter(enum, &rem(&1, 2) == 0) 
...(2)> end) 
[2, 4, 6, 8, 10, 2] 
+0

啊,這是有道理的。但是,我如何通過一個列表來過濾具有範圍元素的列表?例如這裏是我想要按照上面過濾的列表'list = [1..10,2,3]'。 – Bala

+0

您可以使用'Enum.to_list(1..10)++ [2,3]'將其轉換爲平面列表,並將其傳遞給'Enum.flat_map',並在那裏運行'Enum.filter'如果該項目是一個範圍,否則返回'[]'或'[x]'如果該項目是一個數字。 – Dogbert

+0

我已經添加了第二種方法的實現。 – Dogbert

2


要過濾包含數字和範圍的清單,我會用Enum.flat_map這樣。

(1..10) |> Enum.filter(&rem(&1,2)==0) 

在你的榜樣最可讀的解決辦法是:

# declare anonymous function for checking is number even 
is_even = &rem(&1,2) == 0 
(1..10) |> Enum.filter(&is_even.(&1)) 
+2

在第二個中,您可以執行'|> Enum.filter(is_even)''。 :) – Dogbert

+0

@Dogbert:如果你可以在沒有第二個'&,&1'的情況下拋出指針,我將不勝感激。我的意思是什麼時候我需要'&',而當我不需要時? – Bala

+1

@Bala'Enum.filter'需要匿名函數,即'fn ... end'。 '&'語法用於將模塊的函數轉換爲匿名函數。在這種情況下'is_even'已經是一個匿名函數。 '&is_even。(&1)'是多餘的,相當於只是'is_even'。 – Dogbert