ios - the - ¿Encontrar un objeto en la matriz?
the swift programming language pdf (16)
El uso
contains
:
import Foundation
class Model: NSObject { }
O puede probar lo que Martin le indicó, en los comentarios y darle otra oportunidad al
filter
:
Buscar objeto con propiedad en matriz
.
¿Swift tiene algo como _.findWhere en Underscore.js?
Tengo una matriz de estructuras de tipo
T
y me gustaría verificar si la matriz contiene un objeto de estructura cuya propiedad de
name
es igual a
Foo
.
Intenté usar
find()
y
filter()
pero solo funcionan con tipos primitivos, por ejemplo,
String
o
Int
.
Lanza un error sobre no cumplir con el protocolo
Equitable
o algo así.
FWIW, si no desea utilizar una función o extensión personalizada, puede:
let array = [ .... ]
if let found = find(array.map({ $0.name }), "Foo") {
let obj = array[found]
}
Esto genera primero una matriz de
name
y luego la
find
.
Si tiene una gran variedad, es posible que desee hacer:
if let found = find(lazy(array).map({ $0.name }), "Foo") {
let obj = array[found]
}
o tal vez:
if let found = find(lazy(array).map({ $0.name == "Foo" }), true) {
let obj = array[found]
}
Otra forma de obtener acceso a array.index (de: Any) es declarando su objeto
import Dollar
let found = $.find(array) { $0.name == "Foo" }
Para Swift 3,
let numbers = [2, 4, 6, 8, 9, 10]
Por ejemplo, si tuviéramos una serie de números:
let firstOdd = numbers.index { $0 % 2 == 1 }
Podríamos encontrar el primer número impar como este:
let firstOdd = numbers.index { $0 % 2 == 1 }
Eso devolverá 4 como un entero opcional, porque el primer número impar (9) está en el índice cuatro.
Puede filtrar la matriz y luego simplemente elegir el primer elemento, como se muestra en Buscar objeto con propiedad en matriz .
O define una extensión personalizada
struct T {
var name : String
}
let array = [T(name: "bar"), T(name: "baz"), T(name: "foo")]
if let item = array.findFirstMatching( { $0.name == "foo" } ) {
// item is the first matching array element
} else {
// not found
}
Ejemplo de uso:
if let item = array.first(where: { $0.name == "foo" }) {
// item is the first matching array element
} else {
// not found
}
En
Swift 3
puede usar el método existente
first(where:)
(como se
menciona en un comentario
):
func index(where predicate: @noescape Element throws -> Bool) rethrows -> Int?
Puede usar el método de
index
disponible en
Array
con un predicado (
consulte la documentación de Apple aquí
).
func index(where predicate: (Element) throws -> Bool) rethrows -> Int?
Para su ejemplo específico, esto sería:
Swift 5.0
if let i = array.index(where: { $0.name == Foo }) {
return array[i]
}
Swift 3.0
if let i = array.indexOf({ $0.name == Foo }) {
return array[i]
}
Swift 2.0
array.first{$0.name == "Foo"}
Use Dollar que es Lo-Dash o Underscore.js para Swift:
class Person : Equatable { //<--- Add Equatable protocol
let name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
//Add Equatable functionality:
static func == (lhs: Person, rhs: Person) -> Bool {
return (lhs.name == rhs.name)
}
}
SWIFT 5
Verificar si el elemento existe
if array.contains(where: {$0.name == "foo"}) {
// it exists, do something
} else {
//item could not be found
}
Obtén el elemento
if let foo = array.first(where: {$0.name == "foo"}) {
// do something with foo
} else {
// item could not be found
}
Obtener el elemento y su desplazamiento
if let foo = array.enumerated().first(where: {$0.element.name == "foo"}) {
// do something with foo.offset and foo.element
} else {
// item could not be found
}
Consigue el desplazamiento
if let fooOffset = array.firstIndex(where: {$0.name == "foo"}) {
// do something with fooOffset
} else {
// item could not be found
}
Swift 2 o posterior
Puede combinar
indexOf
y
map
para escribir una función "buscar elemento" en una sola línea.
var yourItem:YourType!
if contains(yourArray, item){
yourItem = item
}
El uso de
filter
+
first
ve más limpio, pero
filter
evalúa todos los elementos de la matriz.
indexOf
map
indexOf
+ parece complicado, pero la evaluación se detiene cuando se encuentra la primera coincidencia en la matriz.
Ambos enfoques tienen pros y contras.
Swift 3
Si necesita el objeto, use:
if let index = array.index(where: { $0.name == "Foo" }) {
return array[index]
}
(Si tiene más de un objeto llamado "Foo",
first
devolverá el primer objeto de un pedido no especificado)
Swift 3
puedes usar index (where :) en Swift 3
if let i = theArray.index(where: {$0.name == "Foo"}) {
return theArray[i]
}
ejemplo
if let object = elements.filter({ $0.title == "title" }).first {
print("found")
} else {
print("not found")
}
Swift 3
let array = [T(name: "foo"), T(name: "Foo"), T(name: "FOO")]
let foundValue = array.indexOf { $0.name == "Foo" }.map { array[$0] }
print(foundValue) // Prints "T(name: "Foo")"
Swift 3.0
for myObj in myObjList where myObj.name == "foo" {
//object with name is foo
}
Swift 2.1
El filtrado en las propiedades del objeto ahora es compatible con swift 2.1. Puede filtrar su matriz en función de cualquier valor de la estructura o clase aquí es un ejemplo
for myObj in myObjList where myObj.Id > 10 {
//objects with Id is greater than 10
}
O
extension Array {
// Returns the first element satisfying the predicate, or `nil`
// if there is no matching element.
func findFirstMatching<L : BooleanType>(predicate: T -> L) -> T? {
for item in self {
if predicate(item) {
return item // found
}
}
return nil // not found
}
}
Swift 3:
Puede usar la funcionalidad integrada de Swifts para buscar objetos personalizados en una matriz.
Primero debe asegurarse de que su objeto personalizado se ajuste al protocolo : Equatable .
//create new array and populate with objects:
let p1 = Person(name: "Paul", age: 20)
let p2 = Person(name: "Mike", age: 22)
let p3 = Person(name: "Jane", age: 33)
var people = [Person]([p1,p2,p3])
//find index by object:
let index = people.index(of: p2)! //finds Index of Mike
//remove item by index:
people.remove(at: index) //removes Mike from array
Con la funcionalidad Equatable agregada a su objeto, Swift ahora le mostrará propiedades adicionales que puede usar en una matriz:
let index = array.index(where: {$0.name == "foo"})
Swift 4 ,
Otra forma de lograr esto usando la función de filtro,
if yourArray.contains(item) {
//item found, do what you want
}
else{
//item not found
yourArray.append(item)
}