由于不可变性,我在弄清楚如何使用Elixir更新地图列表时遇到了一些麻烦。这是我目前的失败尝试:
import React, { Component } from "react";
import PropTypes from "prop-types";
import Comment from "./comment";
import axios from "axios";
import Article from "../screens/article";
class Comments extends Component {
constructor(props) {
super(props);
this.state = {
comments: [],
comment: "",
error: ""
};
this.load = this.load.bind(this);
this.comment = this.comment.bind(this);
}
componentDidMount() {
this.load();
}
load() {
return this.props.getComments().then(comments => {
this.setState({ comments });
return comments;
});
}
comment() {
return this.props.submitComment().then(comment => {
this.setState({ comment }).then(this.load);
});
}
render() {
const { comments } = this.state;
return (
<div>
{comments.map(comment => (
<Comment key={comment.id} commment={comment} />
))}
</div>
);
}
}
export default Comments;
此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
函数最多可容纳12个不同的construct_score_table/1
,我想建立一个看起来像这样的地图列表:
p_score
但是我目前的尝试将其完全构建为单独的列表。我该如何不断更新现有列表,并每次都将地图附加为元素?
答案 0 :(得分:1)
就像您已经提到的那样,Elixir是一种功能语言,意味着它具有不变的数据,因此您需要使用流程来管理状态。 有几种方法可以做到这一点:
使用代理的简单示例如下:
defmodule ScoreTable do
use Agent
def start_link do
Agent.start_link(fn -> [] end, name: __MODULE__)
end
def get_all_scores do
Agent.get(__MODULE__, &(&1))
end
def add_score(score) do
Agent.update(__MODULE__, &(&1 ++ [score]))
end
end
现在,一旦应用程序启动,只需启动ScoreTable
代理,您就可以读取/写入分数列表的状态:
# Add a score
ScoreTable.add_score(team_score_map)
# Get all scores back
ScoreTable.get_all_scores
答案 1 :(得分:1)
由于不变性,我在弄清楚如何更新时遇到了一些麻烦 使用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()
返回的列表。
您当然不需要创建其他流程,例如代理或GenServer,以更新Elixir中的列表。