(斯威夫特 3)
检查数组中是否存在元素(满足某些条件),如果存在,则继续处理第一个这样的元素
如果意图是:
- 检查一个元素是否存在于数组中(/满足一些布尔标准,不一定是相等测试),
- 如果是这样,请继续使用第一个此类元素,
那么contains(_:) 的替代方案是Sequence 是first(where:) 的Sequence:
let elements = [1, 2, 3, 4, 5]
if let firstSuchElement = elements.first(where: { $0 == 4 }) {
print(firstSuchElement) // 4
// ...
}
在这个人为的例子中,它的用法可能看起来很傻,但是如果查询非基本元素类型的数组以查找是否存在满足某些条件的任何元素,它就非常有用。例如
struct Person {
let age: Int
let name: String
init(_ age: Int, _ name: String) {
self.age = age
self.name = name
}
}
let persons = [Person(17, "Fred"), Person(16, "Susan"),
Person(19, "Hannah"), Person(18, "Sarah"),
Person(23, "Sam"), Person(18, "Jane")]
if let eligableDriver = persons.first(where: { $0.age >= 18 }) {
print("\(eligableDriver.name) can possibly drive the rental car in Sweden.")
// ...
} // Hannah can possibly drive the rental car in Sweden.
let daniel = Person(18, "Daniel")
if let sameAgeAsDaniel = persons.first(where: { $0.age == daniel.age }) {
print("\(sameAgeAsDaniel.name) is the same age as \(daniel.name).")
// ...
} // Sarah is the same age as Daniel.
任何使用.filter { ... some condition }.first 的链式操作都可以替换为first(where:)。后者更好地显示意图,并且与.filter 的可能的非惰性设备相比具有性能优势,因为它们将在提取(可能的)第一个通过过滤器的元素之前通过完整的数组。
检查数组中是否存在元素(满足某些条件),如果存在,则删除第一个这样的元素
查询下方的评论:
如何从数组中删除firstSuchElement?
与上述类似的用例是删除满足给定谓词的第一个元素。为此,可以使用Collection 的index(where:) 方法(可随时用于数组集合)来查找满足谓词的第一个元素的索引,然后可以将索引与remove(at:) 的方法一起使用Array (可能;假设它存在)删除该元素。
var elements = ["a", "b", "c", "d", "e", "a", "b", "c"]
if let indexOfFirstSuchElement = elements.index(where: { $0 == "c" }) {
elements.remove(at: indexOfFirstSuchElement)
print(elements) // ["a", "b", "d", "e", "a", "b", "c"]
}
或者,如果您想从数组中删除元素并使用,请有条件地应用Optional:s map(_:) 方法(对于.some(...) 从index(where:) 返回) 使用来自index(where:) 的结果从数组中删除并捕获已删除的元素(在可选的绑定子句中)。
var elements = ["a", "b", "c", "d", "e", "a", "b", "c"]
if let firstSuchElement = elements.index(where: { $0 == "c" })
.map({ elements.remove(at: $0) }) {
// if we enter here, the first such element have now been
// remove from the array
print(elements) // ["a", "b", "d", "e", "a", "b", "c"]
// and we may work with it
print(firstSuchElement) // c
}
请注意,在上面的人为示例中,数组成员是简单的值类型(String 实例),因此使用谓词查找给定成员有点过分,因为我们可能只是使用更简单的 @ 来测试相等性987654350@方法如@DogCoffee's answer所示。但是,如果将上述查找和删除方法应用于 Person 示例,则将 index(where:) 与谓词一起使用是合适的(因为我们不再测试相等性,而是满足提供的谓词)。