Переписать фильтр в операторы труб в Elixir - PullRequest
0 голосов
/ 31 августа 2018

Я очень плохо знаком с Эликсиром и пытаюсь переписать это:

kids = ["Mike", "Paula", "Julia", "Phil"]
Enum.filter(kids, fn(n) -> String.contains? n, "i" end)
# results in: ["Mike", "Julia", "Phil"]

в нечто подобное

kids |> Enum.filter String.contains? "i"

Не сработает. - Чего мне не хватает?

Ответы [ 3 ]

0 голосов
/ 31 августа 2018

Попытка сделать это на iex дает нам ошибку:

iex(4)> kids = ["Mike", "Paula", "Julia", "Phil"]                 
["Mike", "Paula", "Julia", "Phil"]
iex(5)> kids |> Enum.filter String.contains? "i" 
warning: parentheses are required when piping into a function call. For example:

    foo 1 |> bar 2 |> baz 3

is ambiguous and should be written as

    foo(1) |> bar(2) |> baz(3)

Ambiguous pipe found at:
  iex:5

** (UndefinedFunctionError) function String.contains?/1 is undefined or private. Did you mean one of:

      * contains?/2

    (elixir) String.contains?("i")

Ошибка в том, что String.contains?/2 ожидает 2 аргумента и был дан только один. Также вторым аргументом Enum.filter/2 должна быть функция. Итак, чтобы избавиться от ошибки, вы можете написать:

iex(1)> kids = ["Mike", "Paula", "Julia", "Phil"]
["Mike", "Paula", "Julia", "Phil"]
iex(2)> kids |> Enum.filter fn(n) -> String.contains? n, "i" end
warning: parentheses are required when piping into a function call. For example:

    foo 1 |> bar 2 |> baz 3

is ambiguous and should be written as

    foo(1) |> bar(2) |> baz(3)

Ambiguous pipe found at:
  iex:2

["Mike", "Julia", "Phil"]

Чтобы сделать конвейер однозначным и избавиться от предупреждения, просто добавьте скобки вокруг вызова функции:

iex(3)> kids = ["Mike", "Paula", "Julia", "Phil"]               
["Mike", "Paula", "Julia", "Phil"]
iex(4)> kids |> Enum.filter(fn(n) -> String.contains? n, "i" end)
["Mike", "Julia", "Phil"]
0 голосов
/ 01 сентября 2018

Вы также можете использовать понимания с фильтром:

for kid <- kids, String.contains?(kid, "i"), do: kid
["Mike", "Julia", "Phil"]
0 голосов
/ 31 августа 2018

Это очень близко, вы можете идти с этим шаг за шагом.

  1. Перемещение kids "до" |>:

    kids |> Enum.filter(fn(n) -> String.contains?(n, "i") end)

  2. Используйте оператор захвата , чтобы сократить фильтрацию функцию:

    kids |> Enum.filter(&String.contains?(&1, "i"))

Надеюсь, это поможет!

...