Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 是否从对象数组中删除匹配项?_Arrays_Swift - Fatal编程技术网

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

Arrays 是否从对象数组中删除匹配项?,arrays,swift,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.") ] var temp = myArr.filter { $0.name == "Def" }.first my

我有这样一个对象数组:

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.removeAll { $0.name == "Def" } // Pseudo
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"}
我知道我可以找到这样的匹配项:

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.removeAll { $0.name == "Def" } // Pseudo
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"}
但是现在如何从原始的
myArr
中删除它呢?我希望
过滤器。首先
可以以某种方式返回索引,这样我就可以使用
removeAtIndex
。或者更好的是,我想这样做:

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.removeAll { $0.name == "Def" } // Pseudo
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"}

有什么想法吗?

使用过滤器获取对象,然后在数组中循环,并使用myArr.removeAtIndex(索引)删除每个对象。使用过滤器正是这样做的。要了解正在发生的事情,请阅读下面的内容。Matts answer是一种更简洁的方法,因为您正在测试相反的匹配,因此每个对象都会被保留,除非它与您的值匹配

循环通过临时过滤器阵列

if let index = find(temp, note) {
   myArr.removeAtIndex(index)
}

您没有掌握的是数组是一个结构,因此是一个值类型。它不能像类实例那样进行原地变异。因此,您将始终在幕后创建一个新数组,即使您扩展数组以编写一个变异的
removeIf
方法

因此,使用
过滤器
和关闭条件的逻辑负数不会有任何缺点,也不会失去通用性:

myArr = myArr.filter { $0.name != "Def" }
例如,您可以这样编写
removeIf

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.removeAll { $0.name == "Def" } // Pseudo
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"}
然后你可以这样使用它:

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.removeAll { $0.name == "Def" } // Pseudo
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"}

但事实上,这是对你时间的极大浪费。您在这里没有做
过滤器
没有做的事情。从
myArr.removeIf
语法中可以看出,您正在适当地变异
myArr
,但您没有;您正在用另一个阵列替换它。实际上,在该循环中,每次调用
removatendex
都会创建另一个数组!因此,您最好使用
过滤器
并感到高兴。

如果您想从正在迭代的数组中删除对象,您应该始终向后迭代,否则您将在某个时候处理不再有效的索引

var myArr = [
    ["key":"value1"],
    ["key":"value2"],
    ["key":"value3"]
]

for index in stride(from: myArr.count - 1 , to: 0, by: -1){
    let x = myArr[index]
    if x["key"] == "value2"{
        myArr.removeAtIndex(index)
    }
}

苹果在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."
var phrase=“西班牙的雨水主要集中在平原。”
let元音:Set=[“a”、“e”、“i”、“o”、“u”]
短语.removeAll(其中:{votels.contains($0)})
//短语==“第n个Spn系统第n个pln。”

较老且回答深思熟虑的帖子,但作为马特上述回答的一个轶事,对于移除单个元素的简单情况,您还可以执行以下操作:

extension Array {
    public func dropFirst(matching: (Element) -> Bool) -> ArraySlice<Element> {
        guard let at = self.firstIndex(where: matching) else { return ArraySlice(self) }
        return prefix(at) + suffix(from: at).dropFirst()
    }
}

For循环是找到索引的唯一方法?。。有一个优雅的结尾吗?
find
只适用于简单数组,而不适用于对象数组,对吗?无法获取
find
来处理对象数组。您已经使用过滤器获取了所有对象,然后您可以使用循环中的find来从另一个数组中删除每个对象。
filter
是“优雅的闭包”(顺便说一句,也是一个循环),对于如何使用每个迭代,以及他是否希望保留原始数组,可能会产生混淆?如果他只需要从数组中删除,那么简单地测试负数就会产生“从数组中删除”的效果。
myArr=myArr.filter{$0.name!=“Def”}
有什么问题?因为这迫使我创建一个新变量。我想修改现有的
myArr
变量。不,它没有
myArr
仍然是
myArr
。这是一种值类型;你不能在原地改变它!您将始终创建一个新数组,即使您编写了一个变异的
removeAll
方法。这里讨论了
removeAll()
实现:.Hi@matt。我如何用不同的对象替换数组中与另一个对象相同的对象,就像我们在swift中的目标C中所做的那样?我无法得到它。请帮忙。这是“正确”的答案。如果你想了解它是如何工作的,那么看看我的。了解这一点对于如何过滤至关重要,更重要的是!=作品这只是说“保留此数组中的所有对象,除非它与“Def”匹配”。我已经更新了答案,以显示实际的
removeIf
实现。所以,若你们真的想,你们可以扩展数组,将其作为一种变异方法。但是,正如我也指出的那样,执行is将毫无意义。
mutating func removeAtIndex()
真的创建了一个新数组吗?@MartinR当然。试试这个:
vararr=[1,2,3]{didSet{println(“did”)};arr.removatendex(1)
。调用
didSet
,证明数组已被替换。把变量
arr
想象成一个鞋盒;我们已经从鞋盒中取出了阵列,并放入了一个不同的阵列。这就是值类型的工作方式。调用值类型实例的mutating func会将该实例替换为新实例。@matt:
arr[0]=2
也会触发
didSet
。这并不是说我不相信你,但如果每个数组元素的赋值都创建了一个完整的新数组,那么这个数组将无法用于任何严肃的工作(想象一个包含1000个方程和1000个未知数的线性方程解算器)。