2013-08-31 14 views
5

Z Enum.find_index/2 (http://elixir-lang.org/docs/master/Enum.html#find_index/2), możemy znaleźć indeks elementu. Jeśli jednak ten sam element występuje kilka razy, jak możemy to zrobić?Znajdź indeksy z listy w eliksiru

chciałbym mieć to zachowanie:

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] 

Dzięki za wszelkie pomysły.

Odpowiedz

2

Nie mogłem znaleźć dokładnej funkcji w bibliotece, więc próbowałem ją zaimplementować. Mam nadzieję, że może trochę pomóc.

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) 

Wykonane następująco,

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

Dziękuję za pomoc @parroty! możemy to również zrobić za pomocą: 'Enum.with_index ([" a "," b "," c "," b "," b "]) |> Enum.filter_map (fn {x, _} -> x = = "b" end, fn {_, i} -> i end) ' – Doug

+0

Tak. To byłoby bardziej eliksiropodobne. – parroty

0

Alternatywnie, można zip listę z zakresu 0..length(list) i filtrować listę używając nowy przedmiot:

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) 

Które filtry elementy nieparzyste na podanej liście ze stdin.

Należy pamiętać, że 100 w zakresie (0..100) musi być długością Twojej listy. Zakładałem, że mam listę 100 przedmiotów.

Powiązane problemy