我有这张地图
%{
total: 38,
value: 22
}
,并想添加密钥:ratio
。有没有一种立即写的方法:
%{
total: 38,
value: 22,
ratio: __SELF__.value / __SELF__.total
}
还是我需要创建另一个地图来实现这一目标?
谢谢
答案 0 :(得分:2)
所有数据都是不可变的,因此您始终必须制作一张新地图。
一种简单的方法,假设您的地图称为map
:
iex> Map.put(map, :ratio, map.value / map.total)
%{ratio: 0.5789473684210527, total: 38, value: 22}
如果您想在地图已经存在之前就创建它,那么最好将total
和value
放入变量中,并使用它们来构建地图:
defmodule Example do
def make_map(total, value) do
%{total: total, value: value, ratio: value / total}
end
end
iex(1)> Example.make_map(38, 22)
%{ratio: 0.5789473684210527, total: 38, value: 22}
答案 1 :(得分:-2)
我真的很想避免将临时映射分配给变量。
好吧,因为特定存储位置的数据是不可变的,所以elixir可以安全地使用指向新集合内这些存储位置的指针。因此,创建具有中间结果的临时变量不会使使用的内存量增加一倍。例如,如果您从一个包含一百万个条目的地图开始,然后创建一个包含一个附加条目的新地图,则您不会使用以下总内存:
old_map new_map
| |
V V
1 million + ( 1 million + 1)
相反,您仅使用以下内存:
new_entry
|
V
1 + pointer_to_old_map
...再加上一些新地图的记账费用。像这样:
old_map
^
|
new_map = %{ +, a: 10}
有没有一种立即写的方法:
%{ total: 38, value: 22, ratio: __SELF__.value / __SELF__.total }
是:
%{
total: 38,
value: 22,
ratio: 22/38
}
现在,如果您要添加比例键的地图列表:
data = [
%{total: 38, value: 22},
%{total: 40, value: 22},
%{total: 44, value: 22}
]
for %{total: t, value: v}=map <- data do
Map.put(map, :ratio, v/t)
end
输出:
[
%{ratio: 0.5789473684210527, total: 38, value: 22},
%{ratio: 0.55, total: 40, value: 22},
%{ratio: 0.5, total: 44, value: 22}
]
在for comprehension
的每次迭代之后,t
和v
的存储位置将立即进行垃圾回收,并使用指向map
的存储位置的指针在新地图中。