2014-06-16 2 views
1

id/item 튜플의 목록 인 컬렉션을 가져 와서 지정된 항목과 id 및 새 항목을 대체해야하는 함수가 있습니다. 어떻게 이런 식으로 어울릴까요?

def update_item(collection, id, new_item) do 
    Enum.map(collection, fn 
    ({ ^id, _ }) -> { id, new_item } 
    (entry) -> entry 
    end) 
end 

CompileError 및 메시지 unbound variable ^id와 함께 실패합니다. 어떻게해야합니까? 이 작업을 수행 할 수있는 좋은 방법이 있습니까? 아니면 다른 방법으로 진행해야합니까?

답변

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] 
+0

아 물론. 고맙습니다. –

2

이 같은 update_item을 정의 할 수 있습니다 고전 꼬리 재귀를 사용 : 해당 ID 입력과 일치하는 경우 두 번째는 단순히 품목을 교체하지 않고 재귀 동안

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}] 

첫 번째 정의는 첫 번째 항목을 대체합니다. 세 번째 방법은 빈 목록에 대한 중지 조건입니다.

+0

감사를이 대답. 그것은 확실히 작동하지만, 내가 받아 들인 대답은 더 짧고 내가 찾는 것이 더 많습니다. –

관련 문제