Enum.reduce 将字符串放入正确的列表中
Enum.reduce to put strings into the right list
我有一个将字符串拆分成多个部分的函数,我需要将这些部分放入 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
错误,我不确定如何解决这个问题。
有什么建议吗?
您需要 return 一个新地图,其中包含更新后的列表,并包含在缩减函数中。一种方法是使用 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)
虽然@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)
或者,如果您更喜欢更冗长(而且速度较慢——请参阅下面有价值的 Dogbert 评论)但易于阅读的方法(基于匹配映射器参数):
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)
我有一个将字符串拆分成多个部分的函数,我需要将这些部分放入 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
错误,我不确定如何解决这个问题。
有什么建议吗?
您需要 return 一个新地图,其中包含更新后的列表,并包含在缩减函数中。一种方法是使用 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)
虽然@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)
或者,如果您更喜欢更冗长(而且速度较慢——请参阅下面有价值的 Dogbert 评论)但易于阅读的方法(基于匹配映射器参数):
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)