我正在尝试根据匹配更新两个列表,但列表一直是空的。
test_list = []
other_list = []
Enum.map(some_maps, fn some_map ->
case some_map do
%{"test" => item} -> test_list ++ [item]
%{"test2" => item} -> other_list ++ [item]
end
end)
我还尝试了test_list ++ item
和test_list = test_list + [item]
我怎么能接近这个?
答案 0 :(得分:4)
Elixir中的变量是不可变的,因此您无法像这样修改它。我这样做:
some_maps = [%{"test" => 1}, %{"test2" => 2}, %{"test" => 3}]
test_list = for %{"test" => item} <- some_maps, do: item
other_list = for %{"test2" => item} <- some_maps, do: item
IO.inspect test_list
IO.inspect other_list
[1, 3]
[2]
如果你只想迭代一次地图,你也可以在这里使用Enum.reduce/3
,但这样做可能足够好而且更优雅。
以下是Enum.reduce/3
:
some_maps = [%{"test" => 1}, %{"test2" => 2}, %{"test" => 3}]
{test_list, other_list} = Enum.reduce(some_maps, {[], []}, fn
%{"test" => item}, {t, o} -> {[item | t], o}
%{"test2" => item}, {t, o} -> {t, [item | o]}
end)
test_list = Enum.reverse(test_list)
other_list = Enum.reverse(other_list)
IO.inspect test_list
IO.inspect other_list
输出与以前相同。
PS:请在将来发布一个完整的示例,在这种情况下,这意味着some_maps
的示例值。
答案 1 :(得分:1)
虽然@Dogbert的答案和往常一样完美,但是有一个明确专用的函数Enum.split_with/2
可以完全按照你想要的那样做,即拆分可枚举的函数:
iex|1 ▶ some_maps = [%{"test" => 1}, %{"test2" => 2}, %{"test" => 3}]
#⇒ [%{"test" => 1}, %{"test2" => 2}, %{"test" => 3}]
iex|2 ▶ Enum.split_with(some_maps, fn
...|2 ▶ %{"test" => _} -> true
...|2 ▶ %{"test2" => _} -> false
...|2 ▶ end)
#⇒ {[%{"test" => 1}, %{"test" => 3}], [%{"test2" => 2}]}
在这种特殊情况下,理解肯定是规则,但在某些情况下它可能会有所帮助。要获取值,应在结果列表中明确获取Map.values/1
。