(Swift 3)
Verifique se existe um elemento em uma matriz (atendendo a alguns critérios) e , se houver, continue trabalhando com o primeiro desses elementos.
Se a intenção for:
- Para verificar se um elemento existe em uma matriz (/ preenche alguns critérios booleanos, não necessariamente testes de igualdade),
- E, nesse caso, continue e trabalhe com o primeiro desses elementos,
Em seguida, uma alternativa para contains(_:)
blueprinted Sequence
é first(where:)
de Sequence
:
let elements = [1, 2, 3, 4, 5]
if let firstSuchElement = elements.first(where: { $0 == 4 }) {
print(firstSuchElement) // 4
// ...
}
Neste exemplo, seu uso pode parecer bobo, mas é muito útil se consultar matrizes de tipos de elementos não fundamentais para a existência de quaisquer elementos que atendam a alguma condição. Por exemplo
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.
Quaisquer operações encadeadas usando .filter { ... some condition }.first
podem ser substituídas favoravelmente por first(where:)
. O último mostra melhor a intenção e tem vantagens de desempenho em relação a possíveis dispositivos não preguiçosos .filter
, pois eles passarão por toda a matriz antes de extrair o (possível) primeiro elemento que passa pelo filtro.
Verifique se existe um elemento em uma matriz (atendendo a alguns critérios) e , se houver, remova o primeiro desses elementos
Um comentário abaixo consulta:
Como posso remover o firstSuchElement
da matriz?
Um caso de uso semelhante ao descrito acima é remover o primeiro elemento que atende a um determinado predicado. Para fazer isso, o index(where:)
método de Collection
(que está prontamente disponível para a coleção de matrizes) pode ser usado para encontrar o índice do primeiro elemento que preenche o predicado, depois o índice pode ser usado com o remove(at:)
método de Array
(possível; dado que ele existe) remova esse elemento.
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"]
}
Ou, se você deseja remover o elemento da matriz e trabalhar com , aplique Optional
o map(_:)
método s para usar condicionalmente (para .some(...)
retornar de index(where:)
) o resultado de index(where:)
para remover e capturar o elemento removido da matriz (dentro de uma cláusula de ligação opcional) .
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
}
Observe que, no exemplo inventado acima, os membros da matriz são tipos simples de valores ( String
instâncias), portanto, usar um predicado para encontrar um determinado membro é um exagero , pois podemos simplesmente testar a igualdade usando o index(of:)
método mais simples , como mostrado na resposta do @ DogCoffee . Se aplicar a abordagem de localização e remoção acima ao Person
exemplo, no entanto, o uso index(where:)
com um predicado é apropriado (já que não testamos mais a igualdade, mas o cumprimento de um predicado fornecido).
if find(elements, 5) != nil { }
não é bom o suficiente?