arrays - for - swift 4 find object in array
¿Cómo encontrar el índice del elemento de la lista en Swift? (16)
Estoy tratando de encontrar un índice de artículos buscando una lista. ¿Alguien sabe cómo hacer eso?
Veo que hay list.StartIndex y list.EndIndex bu Quiero algo como list.index de python ("texto")
Swift 4.2
func index(of element: Element) -> Int?
var alphabets = ["A", "B", "E", "D"]
Ejemplo 1
let index = alphabets.index(where: {$0 == "A"})
Ejemplo 2
if let i = alphabets.index(of: "E") {
alphabets[i] = "C" // i is the index
}
print(alphabets)
// Prints "["A", "B", "C", "D"]"
Como en algunos aspectos, swift es más funcional que orientado a objetos (y las matrices son estructuras, no objetos), use la función "buscar" para operar en la matriz, que devuelve un valor opcional, así que prepárese para manejar un valor nulo:
let arr:Array = ["a","b","c"]
find(arr, "c")! // 2
find(arr, "d") // nil
Actualización para Swift 2.0:
¡La antigua función de find
ya no es compatible con Swift 2.0!
Con Swift 2.0, Array
gana la capacidad de encontrar el índice de un elemento usando una función definida en una extensión de CollectionType
(que implementa Array
):
let arr = ["a","b","c"]
let indexOfA = arr.indexOf("a") // 0
let indexOfB = arr.indexOf("b") // 1
let indexOfD = arr.indexOf("d") // nil
Además, la búsqueda del primer elemento en una matriz que cumple un predicado es compatible con otra extensión de CollectionType
:
let arr2 = [1,2,3,4,5,6,7,8,9,10]
let indexOfFirstGreaterThanFive = arr2.indexOf({$0 > 5}) // 5
let indexOfFirstGreaterThanOneHundred = arr2.indexOf({$0 > 100}) // nil
Tenga en cuenta que estas dos funciones devuelven valores opcionales, como lo hizo la find
anterior.
Actualización para Swift 3.0:
Tenga en cuenta la sintaxis de indexOf ha cambiado. Para los artículos que Equatable
con Equatable
puede usar:
let indexOfA = arr.index(of: "a")
Puede encontrarse una documentación detallada del método en https://developer.apple.com/reference/swift/array/1689674-index
Para los elementos de la matriz que no se ajustan a Equatable
, deberá utilizar el index(where:)
:
let index = cells.index(where: { (item) -> Bool in
item.foo == 42 // test if this is the item you''re looking for
})
Actualización para Swift 4.2:
Con Swift 4.2, el index
ya no se usa, pero se separa en primer firstIndex
y lastIndex
para una mejor aclaración. Dependiendo de si está buscando el primer o último índice del artículo:
let arr = ["a","b","c","a"]
let indexOfA = arr.firstIndex(of: "a") // 0
let indexOfB = arr.lastIndex(of: "a") // 3
Creo que vale la pena mencionar que con los tipos de referencia ( class
) es posible que desee realizar una comparación de identidad , en cuyo caso solo necesita usar el operador de identidad ===
en el cierre del predicado:
Swift 3 / Swift 4:
let person1 = Person(name: "John")
let person2 = Person(name: "Sue")
let person3 = Person(name: "Maria")
let person4 = Person(name: "Loner")
let people = [person1, person2, person3]
let indexOfPerson1 = people.index{$0 === person1} // 0
let indexOfPerson2 = people.index{$0 === person2} // 1
let indexOfPerson3 = people.index{$0 === person3} // 2
let indexOfPerson4 = people.index{$0 === person4} // nil
Tenga en cuenta que la sintaxis anterior utiliza la sintaxis de los cierres finales y es equivalente a:
let indexOfPerson1 = people.index(where: {$0 === person1})
Swift 2: la sintaxis de la función de index
solía ser:
let indexOfPerson1 = people.indexOf{$0 === person1}
* Tenga en cuenta el comment relevante y útil de paulbailey sobre class
tipos de class
que implementan Equatable
, donde debe considerar si debe comparar utilizando ===
(operador de identidad ) o ==
(operador de igualdad ). Si decide hacer coincidir con ==
, simplemente puede usar el método sugerido por otros ( people.index(of: person1)
).
Cualquiera de esta solución me funciona
Esta es la solución que tengo para Swift 4:
let monday = Day(name: "M")
let tuesday = Day(name: "T")
let friday = Day(name: "F")
let days = [monday, tuesday, friday]
let index = days.index(where: {
//important to test with === to be sure it''s the same object reference
$0 === tuesday
})
En Swift 4 , si está atravesando su matriz DataModel, asegúrese de que su modelo de datos cumpla con el Protocolo Equatable, implemente el método lhs = rhs, y solo entonces puede usar ".index (de". Por ejemplo
class Photo : Equatable{
var imageURL: URL?
init(imageURL: URL){
self.imageURL = imageURL
}
static func == (lhs: Photo, rhs: Photo) -> Bool{
return lhs.imageURL == rhs.imageURL
}
}
Y entonces,
let index = self.photos.index(of: aPhoto)
En Swift 2 (con Xcode 7), Array
incluye un método indexOf
proporcionado por el protocolo CollectionType
. (En realidad, dos métodos indexOf
: uno que usa la igualdad para coincidir con un argumento y another que usa un cierre).
Antes de Swift 2, no había una forma para que los tipos genéricos como las colecciones proporcionaran métodos para los tipos concretos derivados de ellos (como matrices). Entonces, en Swift 1.x, "índice de" es una función global ... Y también se le cambió el nombre, así que en Swift 1.x, esa función global se llama find
.
También es posible (pero no necesario) usar el método indexOfObject
de NSArray
... o cualquiera de los otros métodos de búsqueda más sofisticados de Foundation que no tienen equivalentes en la biblioteca estándar de Swift. Simplemente import Foundation
(u otro módulo que importe transitivamente Foundation), convierta su Array
a NSArray
, y puede usar los muchos métodos de búsqueda en NSArray
.
Mientras que indexOf()
funciona perfectamente, solo devuelve un índice.
Buscaba una forma elegante de obtener una serie de índices para elementos que satisfacen alguna condición.
Aquí es cómo se puede hacer:
Swift 3:
let array = ["apple", "dog", "log"]
let indexes = array.enumerated().filter {
$0.element.contains("og")
}.map{$0.offset}
print(indexes)
Swift 2:
let array = ["apple", "dog", "log"]
let indexes = array.enumerate().filter {
$0.element.containsString("og")
}.map{$0.index}
print(indexes)
Para SWIFT 3 puedes usar una función simple
func find(objecToFind: String?) -> Int? {
for i in 0...arrayName.count {
if arrayName[i] == objectToFind {
return i
}
}
return nil
}
Esto le dará la posición del número, por lo que puede utilizar como
arrayName.remove(at: (find(objecToFind))!)
Espero ser útil
Para la clase personalizada, necesita implementar el protocolo Equatable.
import Foundation
func ==(l: MyClass, r: MyClass) -> Bool {
return l.id == r.id
}
class MyClass: Equtable {
init(id: String) {
self.msgID = id
}
let msgID: String
}
let item = MyClass(3)
let itemList = [MyClass(1), MyClass(2), item]
let idx = itemList.indexOf(item)
printl(idx)
Puedes filter
una matriz con un cierre:
var myList = [1, 2, 3, 4]
var filtered = myList.filter { $0 == 3 } // <= returns [3]
Y puedes contar una matriz:
filtered.count // <= returns 1
Así que puedes determinar si una matriz incluye tu elemento combinando estos:
myList.filter { $0 == 3 }.count > 0 // <= returns true if the array includes 3
Si quieres encontrar la posición, no veo una manera elegante, pero ciertamente puedes hacerlo así:
var found: Int? // <= will hold the index if it was found, or else will be nil
for i in (0..x.count) {
if x[i] == 3 {
found = i
}
}
EDITAR
Mientras estamos en ello, para un ejercicio divertido, ampliemos Array
para que tenga un método de find
:
extension Array {
func find(includedElement: T -> Bool) -> Int? {
for (idx, element) in enumerate(self) {
if includedElement(element) {
return idx
}
}
return nil
}
}
Ahora podemos hacer esto:
myList.find { $0 == 3 }
// returns the index position of 3 or nil if not found
Si todavía estás trabajando en Swift 1.x
entonces intenta,
let testArray = ["A","B","C"]
let indexOfA = find(testArray, "A")
let indexOfB = find(testArray, "B")
let indexOfC = find(testArray, "C")
Swift 4. Si su matriz contiene elementos de tipo [String: AnyObject]. Así que para encontrar el índice de elemento use el siguiente código
var array = [[String: AnyObject]]()// Save your data in array
let objectAtZero = array[0] // get first object
let index = (self.array as NSArray).index(of: objectAtZero)
O bien, si desea encontrar el índice sobre la base de la clave del diccionario. Aquí la matriz contiene objetos de clase de modelo y coincido con la propiedad de identificación.
let userId = 20
if let index = array.index(where: { (dict) -> Bool in
return dict.id == userId // Will found index of matched id
}) {
print("Index found")
}
También puede usar la biblioteca funcional Dollar para hacer un indexOf en una matriz como tal http://www.dollarswift.org/#indexof-indexof
$.indexOf([1, 2, 3, 1, 2, 3], value: 2)
=> 1
Actualización para Swift 2:
sequence.contains (elemento) : devuelve verdadero si una secuencia dada (como una matriz) contiene el elemento especificado.
Swift 1:
Si está buscando solo para comprobar si un elemento está contenido dentro de una matriz, es decir, simplemente obtenga un indicador booleano, use contains(sequence, element)
lugar de find(array, element)
:
contiene (secuencia, elemento) : devuelve verdadero si una secuencia dada (como una matriz) contiene el elemento especificado.
Vea el ejemplo a continuación:
var languages = ["Swift", "Objective-C"]
contains(languages, "Swift") == true
contains(languages, "Java") == false
contains([29, 85, 42, 96, 75], 42) == true
if (contains(languages, "Swift")) {
// Use contains in these cases, instead of find.
}
Swift 2.1
var array = ["0","1","2","3"]
if let index = array.indexOf("1") {
array.removeAtIndex(index)
}
print(array) // ["0","2","3"]
Swift 3
var array = ["0","1","2","3"]
if let index = array.index(of: "1") {
array.remove(at: index)
}
array.remove(at: 1)
Swift 4
Para tipos de referencia:
extension Array where Array.Element: AnyObject {
func index(ofElement element: Element) -> Int? {
for (currentIndex, currentElement) in self.enumerated() {
if currentElement === element {
return currentIndex
}
}
return nil
}
}