4

配列内のアイテムを更新する最も簡単で正しい方法は何ですか? 呼び出し元にも更新された配列が必要です。そう:

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
    }

呼び出し元に更新されたアイテム (更新されたアイテムを含む) が必要です。上記のコードの問題は、ローカル変数 item のみを更新することだと思います。アイテム配列内の関連アイテムを実際に更新する最良の方法は何ですか?

4

2 に答える 2

5

スーパーマンがタイツを履くのと同じように、一度に片足ずつ行います。着信配列を循環し、一致inoutする項目を置き換えます。id

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
}

これはinout、ラベルではなくタイプの前にある Swift 3 構文であることに注意してください。

次を使用して、もう少し「迅速に」書くことができますmap

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

……でも、結局は同じこと。

于 2016-12-27T21:25:40.993 に答える
2

配列内のインスタンスitemの単なるコピー (が、、またはItemなどの値型である場合)、またはそれへの参照 (が `class などの参照型である場合) を変更しています。いずれの場合も、配列は影響を受けません。structtupleenumItem

配列内のインスタンスのインデックスを見つけて、そのインデックスで配列を変更する必要があります。

func updateItem(updatedItem: Item, inout items: [Item]) -> Bool {
    guard let index = items.index(where: { $0.id == updatedItem.id }) else {
        return false // No matching 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
}
于 2016-12-27T20:19:53.003 に答える