我正在尝试使用我的代码更高效,但我有一个大脑放屁.我编写的这段代码非常有用,并且完全符合我的要求:它检查数组并删除未知索引处的Object.但我觉得有一种更好,更有效的方式来编写它.我去了Array.remove(at :),但这需要一个已知的索引.我正在进入大O符号,并且不知道如何使这更容易处理.有任何想法吗?
// create a new object array
var sort : [MyCustomObject] = []
//iterate through my object array
for i in objectArray{
if i === objectToRemove{
}
else{
sort.append(i)
}
}
// set old array to sort, which no longer has the unwanted object
self.objectArray = sort
Run Code Online (Sandbox Code Playgroud)
使用firstIndex(where:)(以前index(where:)在Swift 4.1及更早版本中调用)使用谓词在数组中搜索对象{ $0 === objectToRemove },然后调用remove(at:)数组将其删除:
if let idx = objectArray.firstIndex(where: { $0 === objectToRemove }) {
objectArray.remove(at: idx)
}
Run Code Online (Sandbox Code Playgroud)
这允许您搜索您的对象是否是Equatable.
如果您使用 Xcode 10.0+ beta(Swift 4.2 或更高版本)进行编码,则可以使用新方法 removeAll(where:)
mutating func removeAll(where predicate: (Element) throws -> Bool) rethrows
Run Code Online (Sandbox Code Playgroud)
讨论:使用此方法删除集合中满足特定条件的每个元素。 复杂度:O(n),其中 n 是集合的长度。
此示例从数字数组中删除所有奇数:
Swift 5.2 或更高版本
extension BinaryInteger {
var isEven: Bool { isMultiple(of: 2) }
var isOdd: Bool { !isMultiple(of: 2) }
}
var numbers = [5, 6, 7, 8, 9, 10, 11]
numbers.removeAll(where: \.isOdd) // numbers == [6, 8, 10]
numbers
Run Code Online (Sandbox Code Playgroud)
在您的情况下,请确保MyCustomObject符合Equatable
objectArray.removeAll(where: { $0 == objectToRemove })
Run Code Online (Sandbox Code Playgroud)
或使用符合它的属性之一作为谓词(即id: Int):
objectArray.removeAll(where: { $0.id == idToRemove })
Run Code Online (Sandbox Code Playgroud)
注意:如果您没有使用 Xcode 10.0+ beta (Swift 4.2),您可以实现您自己的removeAll(where:)方法,如您在此答案中所见。
实现 a removeFirst(where:)andremoveLast(where:)避免迭代整个集合,如@vacawama 的评论中所述
斯威夫特 4.1
extension RangeReplaceableCollection {
@discardableResult
mutating func removeFirst(where predicate: (Element) throws -> Bool) rethrows -> Element? {
guard let index = try index(where: predicate) else { return nil }
return remove(at: index)
}
}
Run Code Online (Sandbox Code Playgroud)
extension RangeReplaceableCollection where Self: BidirectionalCollection {
@discardableResult
mutating func removeLast(where predicate: (Element) throws -> Bool) rethrows -> Element? {
guard let index = try indices.reversed().first(where: {
try predicate(self[$0])
}) else { return nil }
return remove(at: index)
}
}
Run Code Online (Sandbox Code Playgroud)
Swift 4.2 或更高版本(如@Hamish 所建议)
extension RangeReplaceableCollection {
@discardableResult
mutating func removeFirst(where predicate: (Element) throws -> Bool) rethrows -> Element? {
guard let index = try firstIndex(where: predicate) else { return nil }
return remove(at: index)
}
}
Run Code Online (Sandbox Code Playgroud)
extension RangeReplaceableCollection where Self: BidirectionalCollection {
@discardableResult
mutating func removeLast(where predicate: (Element) throws -> Bool) rethrows -> Element? {
guard let index = try lastIndex(where: predicate) else { return nil }
return remove(at: index)
}
}
Run Code Online (Sandbox Code Playgroud)
您还可以查看这篇文章中的 remove(while:)、removeLast(while:) 和 dropLast(while:) 方法实现。