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

Tru*_*an1 5 arrays swift

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

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

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

var temp = myArr.filter { $0.name == "Def" }.first
Run Code Online (Sandbox Code Playgroud)

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

myArr.removeAll { $0.name == "Def" } // Pseudo
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

mat*_*att 16

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

因此,使用时没有缺点也不会失去一般性,filter而且关闭条件的逻辑否定:

myArr = myArr.filter { $0.name != "Def" }
Run Code Online (Sandbox Code Playgroud)

例如,您可以这样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)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

myArr.removeIf {$0.name == "Def"}
Run Code Online (Sandbox Code Playgroud)

但事实上,这对你的时间来说是一个很大的浪费.你在这里filter没有做任何事情.它可能会出现myArr.removeIf你的变异语法myArr的地方,但你都没有; 你用另一个数组替换它.实际上,在该循环中的每次调用removeAtIndex都会创建另一个数组!所以你不妨使用filter并开心.


小智 5

Apple 在 Swift 4 中添加了您想要的内容:

var phrase = "The rain in Spain stays mainly in the plain."
let vowels: Set<Character> = ["a", "e", "i", "o", "u"]
phrase.removeAll(where: { vowels.contains($0) })
// phrase == "Th rn n Spn stys mnly n th pln."
Run Code Online (Sandbox Code Playgroud)