从具有条件的循环中将项添加到列表中

时间:2018-01-10 00:46:33

标签: elixir

我尝试将某些项目添加到列表中,但仅限于条件为真。 我的函数实际上是在条件为假时存储空数据。

hit_list = for {_mob, %{id: id}} <- get_mob_list(state.mobs) do
  if condition do
    id
  end
end

输出:

[null, "2"]

3 个答案:

答案 0 :(得分:5)

你可以使用for

这样做
hit_list = for {_mob, %{id: id}} <- get_mob_list(state.mobs), condition do
  id
end

例如:

iex(1)> for i <- 1..10, i + 1 < 4, do: i
[1, 2]

答案 1 :(得分:4)

我认为Enum.filter/2将是一种更惯用的方式

Enum.filter(1..10, fn(x) -> rem(x, 2) == 0 end)
[2, 4, 6, 8, 10]

我最初错过了只需要提取ID的要求。在这种情况下,您可以使用List.foldr/3

x = Enum.zip(1..10, [:a,:b,:c,:d,:e,:f,:g,:h,:i,:j])
[{1, :a}, {2, :b}, {3, :c}, {4, :d}, {5, :e}, {6, :f}, {7, :g}, {8, :h}, {9, :i}, {10, :j}]
List.foldr(x, [], fn({x, _}, acc) -> if rem(x, 2) == 0, do: [x | acc], else: acc end)
[2, 4, 6, 8, 10]

答案 2 :(得分:2)

虽然到目前为止这两个答案都是完全有效的,但我会采用更通用的方法来实现更复杂的过滤:Enum.reduce/3

reducer = fn
  i, acc when i + 1 < 4 -> [i | acc]
  _i, acc -> acc
end

1..10
|> Enum.reduce([], reducer)
|> :lists.reverse()
#⇒ [1, 2]

这看起来像是一种矫枉过正,但它比其他两种方式都更强大,并且在comprehensions和普通Enum.filter/2都无法帮助的情况下作为最后的手段来拯救。

旁注:最后一次调用:lists.reverse是必需的,因为reduce会提前撤消输入。