一尘不染

从对象数组中删除匹配项?

swift

我有一个这样的对象数组:

var myArr = [
  MyObject(name: "Abc", description: "Lorem ipsum 1."),
  MyObject(name: "Def", description: "Lorem ipsum 2."),
  MyObject(name: "Xyz", description: "Lorem ipsum 3.")
]

我知道我可以找到匹配的项目,如下所示:

var temp = myArr.filter { $0.name == "Def" }.first

但是现在如何将其从原始文件中删除myArr?我希望filter.first可以以某种方式返回索引,以便可以使用removeAtIndex。或者更好的是,我想做这样的事情:

myArr.removeAll { $0.name == "Def" } // Pseudo

有任何想法吗?


阅读 384

收藏
2020-07-07

共1个答案

一尘不染

您不了解的是Array是一个结构,因此 是一个值类型
。它不能像类实例那样在适当位置进行突变。因此,即使您扩展Array来编写一个变异removeIf方法,您也将始终在幕后创建一个新的数组。

因此,使用filter闭包条件不会造成任何不利影响,也不会失去通用性:

myArr = myArr.filter { $0.name != "Def" }

例如,您 可以这样 编写removeIf

extension Array {
    mutating func removeIf(closure:(T -> Bool)) {
        for (var ix = self.count - 1; ix >= 0; ix--) {
            if closure(self[ix]) {
                self.removeAtIndex(ix)
            }
        }
    }
}

然后您可以像这样使用它:

myArr.removeIf {$0.name == "Def"}

但是实际上,这是浪费大量时间。您在这里filter没有做的事情没有做。从语法上可能会
出现myArr.removeIf您正在突变myArr的地方,但实际上并非如此。您正在用另一个数组替换它。实际上,该循环中的 每个
调用removeAtIndex都会创建另一个数组!因此,您不妨使用filter并感到高兴。

2020-07-07