Respuestas:
Como swift es en algunos aspectos más funcional que orientado a objetos (y las matrices son estructuras, no objetos), use la función "find" 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 find
función anterior 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 Array
implementa):
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, encontrar el 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 find
hizo antes.
Actualización para Swift 3.0:
Tenga en cuenta que la sintaxis de indexOf ha cambiado. Para los artículos que se ajustan a Equatable
usted, puede usar:
let indexOfA = arr.index(of: "a")
Se puede encontrar 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 Equatable
, deberá usar 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, index
ya no se usa, pero se separa en firstIndex
y lastIndex
para una mejor aclaración. Entonces, dependiendo de si está buscando el primer o el ú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
indexOf
una matriz de estructuras que usted mismo definió, su estructura debe cumplir con el Equatable
protocolo.
tl; dr:
Para las clases, podrías estar buscando:
let index = someArray.firstIndex{$0 === someObject}
Respuesta completa:
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 5, Swift 4.2:
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.firstIndex{$0 === person1} // 0
let indexOfPerson2 = people.firstIndex{$0 === person2} // 1
let indexOfPerson3 = people.firstIndex{$0 === person3} // 2
let indexOfPerson4 = people.firstIndex{$0 === person4} // nil
Tenga en cuenta que la sintaxis anterior utiliza la sintaxis de cierre final y es equivalente a:
let indexOfPerson1 = people.firstIndex(where: {$0 === person1})
Swift 4 / Swift 3 - la función solía llamarse index
Swift 2 - la función solía llamarse indexOf
* Tenga en cuenta el comentario relevante y útil de paulbailey sobre los class
tipos que implementan Equatable
, donde debe considerar si debe comparar utilizando ===
( operador de identidad ) o ==
( operador de igualdad ). Si decide hacer coincidir el uso ==
, simplemente puede usar el método sugerido por otros ( people.firstIndex(of: person1)
).
Person
implementa el Equatable
protocolo, esto no sería necesario.
Binary operator '===' cannot be applied to operands of type '_' and 'Post'
, Post
es mi struct ... alguna idea?
structs
(y enums
) son tipos de valor, no tipos de referencia. Solo los tipos de referencia (p class
. Ej. ) Tienen lógica de comparación de identidad ( ===
). Echa un vistazo a las otras respuestas para saber qué hacer structs
(básicamente, simplemente usas el array.index(of: myStruct)
, asegurándote de que el tipo se myStruct
ajusta a Equatable
( ==
)).
Puede 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
Para que pueda determinar si una matriz incluye su 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 eso, para un ejercicio divertido, extendamos Array
para tener un find
método:
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
Array
para tener un find
método que haga lo que quieras. Todavía no sé si esta es una buena práctica, pero es un buen experimento.
enumerate
para que no se aplique, pero tiene toda la razón.
func firstIndex(of element: Element) -> Int?
var alphabets = ["A", "B", "E", "D"]
Ejemplo 1
let index = alphabets.firstIndex(where: {$0 == "A"})
Ejemplo2
if let i = alphabets.firstIndex(of: "E") {
alphabets[i] = "C" // i is the index
}
print(alphabets)
// Prints "["A", "B", "C", "D"]"
Si bien indexOf()
funciona perfectamente, solo devuelve un índice.
Estaba buscando una forma elegante de obtener una variedad de índices para elementos que satisfagan alguna condición.
Así es como 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 la clase personalizada, debe 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)
Actualización para Swift 2:
secuencia.contains (elemento) : Devuelve verdadero si una secuencia dada (como una matriz) contiene el elemento especificado.
Swift 1:
Si solo busca verificar si un elemento está contenido dentro de una matriz, es decir, solo obtenga un indicador booleano, use en contains(sequence, element)
lugar de find(array, element)
:
contiene (secuencia, elemento) : devuelve verdadero si una secuencia dada (como una matriz) contiene el elemento especificado.
Ver 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.
}
en Swift 4.2
.index (donde :) se cambió a .firstIndex (donde :)
array.firstIndex(where: {$0 == "person1"})
Swift 4. Si su matriz contiene elementos de tipo [String: AnyObject]. Entonces, para encontrar el índice del 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 en función de la clave del diccionario. Aquí la matriz contiene objetos de la clase Modelo y estoy haciendo coincidir la propiedad id.
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")
}
OR
let storeId = Int(surveyCurrent.store_id) // Accessing model key value
indexArrUpTo = self.arrEarnUpTo.index { Int($0.store_id) == storeId }! // Array contains models and finding specific one
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)
let array
? El uso de self
es cuestionable también.
En Swift 4 , si está atravesando su matriz DataModel, asegúrese de que su modelo de datos cumpla con el Protocolo Equivalente, 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 indexOf
método proporcionado por el CollectionType
protocolo. (En realidad, dos indexOf
métodos: uno que usa la igualdad para un argumento y otro 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 las matrices). Entonces, en Swift 1.x, "índice de" es una función global ... Y también se renombró, así que en Swift 1.x, esa función global se llama find
.
También es posible (pero no necesario) usar el indexOfObject
método 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. Solo import Foundation
(u otro módulo que importe de manera transitiva Foundation), emite tuArray
a NSArray
, y puede usar los muchos métodos de búsqueda NSArray
.
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
})
También puede usar la biblioteca funcional Dollar para hacer un indexOf en una matriz como http://www.dollarswift.org/#indexof-indexof
$.indexOf([1, 2, 3, 1, 2, 3], value: 2)
=> 1
Si todavía está 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")
Para SWIFT 3 puede 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 usar como
arrayName.remove(at: (find(objecToFind))!)
Espero ser útil
SWIFT 4
Digamos que desea almacenar un número de la matriz llamada cardButtons en cardNumber, puede hacerlo de esta manera:
let cardNumber = cardButtons.index(of: sender)
remitente es el nombre de su botón
En Swift 4/5, use "firstIndex" para encontrar el índice.
let index = array.firstIndex{$0 == value}
En caso de que alguien tenga este problema
Cannot invoke initializer for type 'Int' with an argument list of type '(Array<Element>.Index?)'
solo haz esto
extension Int {
var toInt: Int {
return self
}
}
entonces
guard let finalIndex = index?.toInt else {
return false
}
por (>= swift 4.0)
Es bastante muy simple. Considere el siguiente Array
objeto.
var names: [String] = ["jack", "rose", "jill"]
Para obtener el índice del elemento rose
, todo lo que tiene que hacer es:
names.index(of: "rose") // returns 1
Nota:
Array.index(of:)
devuelve un Optional<Int>
.
nil
implica que el elemento no está presente en la matriz.
Es posible que desee desenrollar forzosamente el valor devuelto o usar un if-let
para evitar lo opcional.