2016-12-27 11 views
2

배열의 항목을 업데이트하는 가장 쉬운 방법은 무엇입니까? 호출자가 업데이트 된 배열을 가지기를 바랍니다. 따라서 :참조로 전달 된 배열의 항목 업데이트

static func updateItem(updatedItem: Item, inout items: [Item]) -> Bool { 
     var item = items.filter{ $0.id == updatedItem.id }.first 
     if item != nil { 
      item = updatedItem 
      return true 
     } 

     return false 
    } 

호출자가 업데이트 된 항목 (업데이트 된 항목 포함)을 갖기를 원합니다. 위 코드의 문제는 로컬 변수 항목 만 업데이트한다는 것입니다. items 배열 내의 관련 항목을 실제로 업데이트하는 가장 좋은 방법은 무엇입니까? 단순히 배열의 인스턴스의 복사본 넌 item 돌연변이되어

+0

'id'가 같은 기존 항목이 없다면 'updatedItem'에 무엇을 원하겠습니까? – Alexander

답변

3

수퍼맨이 한 번에 한 다리 씩 자신의 스타킹에 오는 것과 같은 방식으로합니다. 수신 inout 배열 순환 및 제품을 대체 여기서 id 일치 :

inout가 입력하지 라벨 선행 3 스위프트 신택스임을
func updateItem(updatedItem: Item, items: inout [Item]) -> Bool { 
    var result = false 
    for ix in items.indices { 
     if items[ix].id == updatedItem.id { 
      items[ix] = updatedItem 
      result = true 
     } 
    } 
    return result 
} 

참고.

func updateItem(updatedItem: Item, items: inout [Item]) { 
    items = items.map { 
     $0.id == updatedItem.id ? updatedItem : $0 
    } 
} 

을 ...하지만 그건 결국 똑같은 금액 :

당신은 map를 사용하여 좀 더 "Swiftily"를 쓸 수 있습니다.

+0

발신자가 항목을 찾았는지에 따라 몇 가지 추가 작업을 수행하기 때문에 bool을 반환합니다. 항목이 "신속하게"접근 할 수 없다면 어떻게 false를 반환 할 수 있습니까? – Prabhu

+0

Bool을 반환하는 첫 번째 방법을 다시 작성 했으므로 사용하는 것이 좋습니다. 두 번째 방법을 사용하면 절약 효과는 없습니다.'map '은 여전히 ​​루프입니다. – matt

2

Item는 참조 타입 인 경우 (또는 그것에 대한 참조 (Item 이러한 struct, tuple 또는 enum 같이 값 유형 인 경우) 클래스와 같은). 두 경우 모두, 배열은 영향을받지 않습니다.

배열 내의 인스턴스 색인을 찾은 다음 해당 색인에서 배열을 변경해야합니다.

func updateItem(updatedItem: Item, inout items: [Item]) -> Bool { 
    guard let index = items.index(where: { $0.id == updatedItem.id }) else { 
     return false // No mathching item found 
    } 

    items[index] = updatedItem 
    return true 
} 

이 모든 것은 다소 복잡합니다. 대신 사전을 사용하여 id을 해당 인스턴스 id에 매핑하면 더 좋습니다. 이것은 당신이 빠르고, 일정한 시간을 보게 될 것이라는 것을 의미하며, 그것은 더 편리 할 것입니다. 그 모양은 다음과 같습니다.

// Assuming the "id" is an Int 
func updateItem(updatedItem: Item, items: inout [Int: Item]) -> Bool { 
    return items.updateValue(updatedItem, forKey: updatedItem.id) != nil 
} 
+0

감사합니다. 사전으로 전화 코드가 어떻게 보이나요? – Prabhu

+1

동일하면 새로운 항목과 모든 항목의 딕트를 전달하십시오 – Alexander

+0

흠, [Item] 유형의 값에 멤버 색인이 없습니다. – Prabhu