ios - descargar - Buscar objeto con propiedad en matriz
swift download (5)
¿existe la posibilidad de obtener un objeto de una matriz con una propiedad específica? ¿O necesito recorrer todos los objetos en mi matriz y verificar si una propiedad es la específica que estaba buscando?
editar: Gracias por darme en la dirección correcta, pero tengo un problema para convertir esto.
// editar de nuevo: A ok, y si solo hay un resultado específico? ¿Es este también un posible método para hacer eso?
let imageUUID = sender.imageUUID
let questionImageObjects = self.formImages[currentSelectedQuestion.qIndex] as [Images]!
// this is working
//var imageObject:Images!
/*
for (index, image) in enumerate(questionImageObjects) {
if(image.imageUUID == imageUUID) {
imageObject = image
}
}
*/
// this is not working - NSArray is not a subtype of Images- so what if there is only 1 possible result?
var imageObject = questionImageObjects.filter( { return $0.imageUUID == imageUUID } )
// esto no funciona, NSArray no es un subtipo de imágenes, entonces, ¿qué sucede si solo hay 1 resultado posible?
No tiene forma de demostrar en tiempo de compilación que solo hay un resultado posible en una matriz. Lo que realmente está pidiendo es el primer resultado coincidente. Lo más fácil (aunque no lo más rápido) es tomar el primer elemento del resultado del filtro:
let imageObject = questionImageObjects.filter{ $0.imageUUID == imageUUID }.first
imageObject
ahora será opcional, por supuesto, ya que es posible que nada coincida.
Si la búsqueda de toda la matriz lleva mucho tiempo, por supuesto, puede crear fácilmente una función
firstMatching
que devolverá el primer elemento (opcional) que coincida con el cierre, pero para las matrices cortas esto está bien y es simple.
Como señala Charles, en Swift 3 está integrado en:
questionImageObjects.first(where: { $0.imageUUID == imageUUID })
Aquí hay otra forma de obtener un objeto en particular mediante el uso de la propiedad del objeto para buscar un objeto en la matriz.
if arrayTicketsListing.contains({ $0.status_id == "2" }) {
let ticketStatusObj: TicketsStatusList = arrayTicketsListing[arrayTicketsListing.indexOf({ $0.status_id == "2" })!]
print(ticketStatusObj.status_name)
}
Mientras que mi arrayTicketsListing es
[TicketsStatusList]
contiene objetos de la clase
TicketsStatusList
.
// TicketsStatusList class
class TicketsStatusList {
internal var status_id: String
internal var status_name: String
init(){
status_id = ""
status_name = ""
}
}
Aquí hay un ejemplo de trabajo en Swift 4
class Point{
var x:Int
var y:Int
init(x:Int, y:Int){
self.x = x
self.y = y
}
}
var p1 = Point(x:1, y:2)
var p2 = Point(x:2, y:3)
var p3 = Point(x:1, y:4)
var points = [p1, p2, p3]
// Find the first object with given property
let firstMatchingPoint = points.first{$0.x == 1}
// Find all objects with given property
let allMatchingPoints = points.filter{$0.x == 1}
Referencia: cierre final
Sí, puede usar el método de
filter
que toma un cierre donde puede establecer su expresión lógica.
Ejemplo:
struct User {
var firstName: String?
var lastName: String?
}
let users = [User(firstName: "John", lastName: "Doe"), User(firstName: "Bill", lastName: "Clinton"), User(firstName: "John", lastName: "Travolta")];
let johns = users.filter( { return $0.firstName == "John" } )
Tenga en cuenta que
filter
devuelve una matriz que contiene todos los elementos que satisfacen la expresión lógica.
Más información en la Referencia de la Biblioteca
Editar 2016-05-05:
Swift 3 incluirá
first(where:)
.
En Swift 2, puede usar
indexOf
para encontrar el índice del primer elemento de matriz que coincide con un predicado.
let index = questionImageObjects.indexOf({$0.imageUUID == imageUUID})
Esto es un poco más rápido en comparación con el
filter
ya que se detendrá después del primer partido.
(Alternativamente, podría usar una secuencia
lazy
).
Sin embargo, es un poco molesto que solo pueda obtener el índice y no el objeto en sí. Utilizo la siguiente extensión por conveniencia:
extension CollectionType {
func find(@noescape predicate: (Self.Generator.Element) throws -> Bool) rethrows -> Self.Generator.Element? {
return try indexOf(predicate).map({self[$0]})
}
}
Entonces lo siguiente funciona:
questionImageObjects.find({$0.imageUUID == imageUUID})