2013-08-31 116 views
5

With Enum.find_index/2http://elixir-lang.org/docs/master/Enum.html#find_index/2),我們可以找到元素的索引。 但是,如果同一個元素出現好幾次,我們該怎麼辦?從Elixir的列表中查找索引

我想有這種行爲:

iex> find_indexes(["a", "b", "c", "b", "b"], fn(x) -> x == "a" end) 
[0] 

iex> find_indexes(["a", "b", "c", "b", "b"], fn(x) -> x == "c" end) 
[2] 

iex> find_indexes(["a", "b", "c", "b", "b"], fn(x) -> x == "b" end) 
[1, 3, 4] 

感謝您的任何想法。

回答

2

我在庫中找不到確切的函數,所以試圖實現它。希望它可以幫助一些。

defmodule Sample1 do 
    # combining Enum functions 
    def find_indexes(collection, function) do 
    Enum.filter_map(Enum.with_index(collection), fn({x, _y}) -> function.(x) end, elem(&1, 1)) 
    end 
end 

defmodule Sample2 do 
    # implementing as similar way as Enum.find_index 
    def find_indexes(collection, function) do 
    do_find_indexes(collection, function, 0, []) 
    end 

    def do_find_indexes([], _function, _counter, acc) do 
    Enum.reverse(acc) 
    end 

    def do_find_indexes([h|t], function, counter, acc) do 
    if function.(h) do 
     do_find_indexes(t, function, counter + 1, [counter|acc]) 
    else 
     do_find_indexes(t, function, counter + 1, acc) 
    end 
    end 
end 

IO.puts "Sample1" 
IO.inspect Sample1.find_indexes(["a", "b", "c", "b", "b"], fn(x) -> x == "a" end) 
IO.inspect Sample1.find_indexes(["a", "b", "c", "b", "b"], fn(x) -> x == "c" end) 
IO.inspect Sample1.find_indexes(["a", "b", "c", "b", "b"], fn(x) -> x == "b" end) 

IO.puts "Sample2" 
IO.inspect Sample2.find_indexes(["a", "b", "c", "b", "b"], fn(x) -> x == "a" end) 
IO.inspect Sample2.find_indexes(["a", "b", "c", "b", "b"], fn(x) -> x == "c" end) 
IO.inspect Sample2.find_indexes(["a", "b", "c", "b", "b"], fn(x) -> x == "b" end) 

如下執行,

% elixir find.ex 
Sample1 
[0] 
[2] 
[1, 3, 4] 
Sample2 
[0] 
[2] 
[1, 3, 4] 
+3

謝謝你的幫助@parroty!我們也可以這樣做:'Enum.with_index([「a」,「b」,「c」,「b」,「b」])> Enum.filter_map(fn {x,_} - > x = =「b」end,fn {_,i} - > i end)' – Doug

+0

是的。這會更像長生不老藥。 – parroty

0

或者,你可以用一系列0..length(list)壓縮的列表,並使用新的項目篩選列表:

line = IO.read(:stdio, :all) 
|> String.split 
|> Enum.zip(0..100) 
|> Enum.filter(fn({_, x}) -> rem(x, 2) != 0 end) 
|> Enum.map(fn({x, _}) -> "#{x}\n" end) 

哪個過濾奇數元素從stdin給出的列表中。

請注意,範圍內的100個(0..100)必須是您列表的長度。我以爲我有一個100件物品的清單。