Enum.reduce, чтобы поместить строки в правильный список - PullRequest
0 голосов
/ 04 мая 2018

У меня есть эта функция, которая разбивает строку на части, и мне нужно поместить эти части в правильный список на карте params.

parts = String.split(term_string, " ")

params = %{
  search_terms: [],
  wildcard_terms: [],
  minus_terms: [],
  room_terms: [],
  messages_to_terms: [],
  messages_from_terms: [],
  date_before_terms: [],
  date_after_terms: [],
  date_on_terms: [],
  date_during_terms: []
}

Enum.reduce(parts, params, fn p ->
  cond do
    String.ends_with?(p, "*") ->
      params[:wildcard_terms] = [p | params[:wildcard_terms]]

    true ->
      params[:search_terms] = [p | params[:search_terms]]
  end
end)

Я получаю cannot invoke remote function Access.get/2 inside match ошибку прямо сейчас, и я не знаю, как решить проблему.

Есть предложения?

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Хотя решение @ Dogbert, безусловно, идеально надежное, я бы немного изменил этот код, чтобы сделать его более лаконичным:

Enum.reduce(parts, params, fn p ->
  key =
    if String.ends_with?(p, "*") do
      :wildcard_terms
    else
      :search_terms
    end

  Map.update!(params, key, fn ps -> [p | ps] end)
end)

или, если вы предпочитаете более подробный (и медленный - см. Ценный комментарий Догберта ниже), но простой для чтения подход (основанный на сопоставлении аргумента mapper):

parts
|> Enum.map(&String.reverse/1)
|> Enum.reduce(params, fn
     <<"*", _::binary>> = p -> 
       %{params | wildcard_terms: [p | params.wildcard_terms]}
     p ->
       %{params | search_terms: [p | params.search_terms]}
   end)
0 голосов
/ 04 мая 2018

Вам нужно вернуть новую карту с обновленным списком внутри в сокращающей функции. Один из способов сделать это - использовать Map.update!:

Enum.reduce(parts, params, fn p ->
  cond do
    String.ends_with?(p, "*") ->
      Map.update!(params, :wildcard_terms, fn ps -> [p | ps] end)

    true ->
      Map.update!(params, :search_terms, fn ps -> [p | ps] end)
  end
end)
...