(Swift 3)
Проверьте, существует ли элемент в массиве (удовлетворяющий некоторым критериям), , и если да, продолжайте работу с первым таким элементом
Если намерение:
- Чтобы проверить, существует ли элемент в массиве (/ удовлетворяет некоторым логическим критериям, не обязательно проверке равенства),
- И если это так, продолжайте работу с первым таким элементом,
Тогда альтернативой contains(_:)
в соответствии с планом Sequence
является _ 3_ из 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
из массива?
Пример использования, аналогичный приведенному выше, - удалить первый элемент, удовлетворяющий заданному предикату. Для этого метод index(where:)
_ 12_ (который легко доступен для коллекции массивов) может быть используется для поиска индекса первого элемента, выполняющего предикат, после чего индекс можно использовать с 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 _ 17_ для условного (для .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
), поэтому использование предиката для поиска заданного элемента несколько излишне, поскольку мы могли бы просто проверить равенство, используя более простой метод index(of:)
, как показано в ответ @ DogCoffee. Однако, если применить подход поиска и удаления выше к примеру Person
, использование index(where:)
с предикатом уместно (поскольку мы больше не проверяем равенство, а выполняем предоставленный предикат).
person
dfrib
schedule
01.11.2016
if find(elements, 5) != nil { }
недостаточно хорош? - person Martin R   schedule 08.06.2014