我有一个函数,它接受一个id / item元组列表的集合,并且应该替换给定的项目以及id和new item。
def update_item(collection, id, new_item) do
Enum.map(collection, fn
({ ^id, _ }) -> { id, new_item }
(entry) -> entry
end)
end
此操作因CompileError
和消息unbound variable ^id
而失败。我怎样才能做到这一点?有没有一个好方法可以做到这一点,还是我应该采取另一种方式?
答案 0 :(得分:3)
你可以使用警卫:
iex(1)> collection = [a: 1, b: 2, c: 3, b: 4]
iex(2)> id = :b
iex(3)> new_item = 5
iex(4)> Enum.map(collection, fn
({coll_id, _ }) when coll_id == id -> { id, new_item }
(entry) -> entry
end)
[a: 1, b: 5, c: 3, b: 5]
答案 1 :(得分:2)
使用经典尾递归,您可以像这样定义update_item
:
def update_item([{ id, _} | t], id, new_item) do
[{id, new_item} | update_item(t, id, new_item)]
end
def update_item([h | t], id, new_item) do
[h | update_item(t, id, new_item)]
end
def update_item([], _, _) do
[]
end
update_item([{4, 56}, {1, 44}, {1, 33}, {2, 55}], 1, 23)
# => [{4, 56}, {1, 23}, {1, 23}, {2, 55}]
如果第一个定义的id与输入匹配,则第一个定义替换第一个项目,而第二个定义只是在不替换项目的情况下递归。第三种方法是空列表的停止条件。