我想更新地图,执行以下操作:
def updateInfo() do
person = %{ person | name : "new name", age : person.age +1, observation : changeObs(person.age)}
end
def changeObs(age), when age >= 18, do: "Adult"
def changeObs(age), do: "kid"
如果我更新了信息()并且年龄为17岁,我希望此人将观察结果更改为“成人”。但它没有用。我认为地图的更新是按顺序完成的,但显然不是,所以我不能依赖现在年龄为18的事实。如果我像这样拆分更新,我可以这样做:
person = %{ person | name : "new name", age : person.age +1}
person = %{ person | observation : changeObs(person.age)}
有没有办法将所有更新保留在一行中,依赖于以前地图上属性的更新?
答案 0 :(得分:2)
好吧,据我所知,您可以将新值缓存在变量中:
new_age = person.age + 1
person = %{ person | name: "new name", age: new_age, observation: changeObs(new_age)}
或者你可以这样改变:
person
|> Map.put(:name, "new_name")
|> Map.put(:age, new_age)
|> Map.put(:observation, changeObs(new_age))
答案 1 :(得分:1)
首先,更新地图的语法使用冒号,而不是等号。您的代码会引发SyntaxError
异常。
有很多方法可以像oneliner一样完成任务:
person = with age <- person.age + 1,
do: %{person | age: age,
observation: (if age >= 18, do: "Adult", else: "Kid")}
或者:
person = (age = person.age + 1;
%{person | age: age,
observation: (if age >= 18, do: "Adult", else: "Kid")})
或管道链:
{_, person} = person
|> Map.put(:age, person.age + 1)
|> Map.get_and_update(:age, fn age ->
{age, age + 1}
end)
惯用语将是最后一个。我最喜欢的是第一个。