Find Indexes from a List in Elixir

With Enum.find_index/2 ( http://elixir-lang.org/docs/master/Enum.html#find_index/2 ) we can find the index of the element. However, if the same element occurs several times, how can we do this?

I would like to have this behavior:

 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] 

Thanks for any ideas.

+6
source share
2 answers

I could not find the exact function in the library, so I tried to implement it. Hope this can help someone.

 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) 

It is carried out as follows:

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

Alternatively, you can 0..length(list) list with a range of 0..length(list) and filter the list using a new element:

 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) 

Which filter has odd elements in the specified list from stdin.

Note that 100 in the range ( 0..100 ) should be the length of your list. I suggested that I have a list of 100 items.

0
source

Source: https://habr.com/ru/post/952894/


All Articles