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
    }

我希望调用者拥有更新的项目(带有更新的项目)。我认为上面代码的问题在于它只更新了局部变量项。实际更新 items 数组中相关项目的最佳方法是什么?

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
}

请注意,这是 Swift 3 语法,inout在类型之前,而不是标签。

您可以使用以下方法更“迅速”地编写它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是值类型,例如 a structtupleenum),或者是对它的引用(如果Item是引用类型,例如 `class)。在任何一种情况下,阵列都不会受到影响。

您需要在数组中找到实例的索引,然后在该索引处改变数组。

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到带有 that 的实例,那会更好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 回答