首页 > 解决方案 > 不断更新列表状态

问题描述

由于不可变性,我在弄清楚如何使用 Elixir 更新地图列表时遇到了一些麻烦。这是我目前失败的尝试:

defp score_table_map(question, team) do
  prediction_score = Enum.find(team.prediction_scores, &(&1.question_id == question.id))
  construct_score_table(p_score)
end

defp construct_score_table(p_score) do
  information_map = []
  information_map = information_map ++ [%{team_score: p_score.score, team_id: p_score.team_id}]
end

construct_score_table/1函数最多接受 12 个不同p_score的 ',我想构建一个如下所示的地图列表:

[ 
  %{team_score: p_score.score, team_id: p_score.team_id},
  %{team_score: p_score.score, team_id: p_score.team_id},
  %{team_score: p_score.score, team_id: p_score.team_id},
  %{team_score: p_score.score, team_id: p_score.team_id},
]

但我目前的尝试完全将其构建为单独的列表。我怎样才能不断更新现有列表并每次都将地图作为元素附加?

标签: elixir

解决方案


由于不可变性,我在弄清楚如何使用 Elixir 更新地图列表时遇到了一些麻烦。

在函数式语言中,您将数据传递给函数,函数将数据转换并返回。所以,做你想做的最简单的方法是将映射列表与 pscore 一起传递给你的函数。然后该函数可以返回一个新的地图列表。这是一个例子:

defmodule PScore do
  defstruct score: 0, team_id: 0
end

defmodule My do

  def update_pscores(list_of_maps, p_score) do
    [%{team_score: p_score.score, team_id: p_score.team_id} | list_of_maps]
  end

  def go do
    pscore = %PScore{score: 3, team_id: 1}
    pscores = update_pscores([], pscore)
    pscore = %PScore{score: 4, team_id: 2}
    pscores = update_pscores(pscores, pscore)
    IO.puts(inspect pscores)
  end

end

My.go

在iex中编译:

> c "my.exs"       
warning: redefining module PScore (current version defined in memory)
  my.exs:1

warning: redefining module My (current version defined in memory)
  my.exs:5

[%{team_id: 2, team_score: 4}, %{team_id: 1, team_score: 3}] 
[My, PScore]

如果您想保持 pscore 映射与它们添加到列表中的顺序相同,您可以Enum.reverse()使用update_pscores().

您当然不需要创建另一个进程(例如 Agent 或 GenServer)来更新 Elixir 中的列表。


推荐阅读