Respostas:
Como o swift é, em alguns aspectos, mais funcional do que o orientado a objetos (e Arrays são estruturas, não objetos), use a função "find" para operar na matriz, que retorna um valor opcional, portanto, esteja preparado para lidar com um valor nulo:
let arr:Array = ["a","b","c"]
find(arr, "c")! // 2
find(arr, "d") // nil
Atualização para o Swift 2.0:
A find
função antiga não é mais suportada no Swift 2.0!
Com o Swift 2.0, Array
obtém a capacidade de encontrar o índice de um elemento usando uma função definida em uma extensão 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
Além disso, a localização do primeiro elemento em uma matriz que cumpre um predicado é suportada por outra extensão 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
Observe que essas duas funções retornam valores opcionais, como find
antes.
Atualização para o Swift 3.0:
Observe que a sintaxe de indexOf foi alterada. Para itens em conformidade com Equatable
você, você pode usar:
let indexOfA = arr.index(of: "a")
Uma documentação detalhada do método pode ser encontrada em https://developer.apple.com/reference/swift/array/1689674-index
Para itens de matriz que não estão em conformidade, Equatable
você precisará usar index(where:)
:
let index = cells.index(where: { (item) -> Bool in
item.foo == 42 // test if this is the item you're looking for
})
Atualização para o Swift 4.2:
Com o Swift 4.2, index
não é mais usado, mas é separado firstIndex
e lastIndex
para melhor esclarecimento. Portanto, dependendo de você estar procurando o primeiro ou o último índice do item:
let arr = ["a","b","c","a"]
let indexOfA = arr.firstIndex(of: "a") // 0
let indexOfB = arr.lastIndex(of: "a") // 3
indexOf
um conjunto de estruturas que você mesmo definiu, sua estrutura deve estar em conformidade com o Equatable
protocolo.
tl; dr:
Para as aulas, você pode estar procurando:
let index = someArray.firstIndex{$0 === someObject}
Resposta completa:
Eu acho que vale a pena mencionar que, com os tipos de referência ( class
), você pode querer fazer uma comparação de identidade ; nesse caso, você só precisa usar o ===
operador de identidade no fechamento do 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
Observe que a sintaxe acima usa a sintaxe de fechamento à direita e é equivalente a:
let indexOfPerson1 = people.firstIndex(where: {$0 === person1})
Swift 4 / Swift 3 - a função costumava ser chamada index
Swift 2 - a função costumava ser chamada indexOf
* Observe o comentário relevante e útil de paulbailey sobre os class
tipos implementados Equatable
, nos quais é necessário considerar se você deve comparar usando ===
( operador de identidade ) ou ==
( operador de igualdade ). Se você decidir combinar o uso ==
, poderá simplesmente usar o método sugerido por outras pessoas ( people.firstIndex(of: person1)
).
Person
implementado o Equatable
protocolo, isso não seria necessário.
Binary operator '===' cannot be applied to operands of type '_' and 'Post'
, Post
é o meu struct ... alguma idéia?
structs
(e enums
) são tipos de valor, não tipos de referência. Somente tipos de referência (por exemplo class
) possuem lógica de comparação de identidade ( ===
). Confira as outras respostas sobre o que fazer structs
(basicamente você simplesmente usa o array.index(of: myStruct)
, certificando-se de que o tipo myStruct
está em conformidade com Equatable
( ==
)).
Você pode filter
uma matriz com um fechamento:
var myList = [1, 2, 3, 4]
var filtered = myList.filter { $0 == 3 } // <= returns [3]
E você pode contar uma matriz:
filtered.count // <= returns 1
Portanto, você pode determinar se uma matriz inclui seu elemento combinando estes:
myList.filter { $0 == 3 }.count > 0 // <= returns true if the array includes 3
Se você deseja encontrar a posição, não vejo uma maneira elegante, mas certamente você pode fazê-lo assim:
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
Enquanto estamos nisso, para um exercício divertido, vamos estender Array
para ter um find
método:
extension Array {
func find(includedElement: T -> Bool) -> Int? {
for (idx, element) in enumerate(self) {
if includedElement(element) {
return idx
}
}
return nil
}
}
Agora podemos fazer isso:
myList.find { $0 == 3 }
// returns the index position of 3 or nil if not found
Array
para ter um find
método que faça o que você deseja. Ainda não sei se essa é uma boa prática, mas é uma experiência interessante.
enumerate
lo, para que não se aplique mais, mas você está absolutamente certo.
func firstIndex(of element: Element) -> Int?
var alphabets = ["A", "B", "E", "D"]
Exemplo 1
let index = alphabets.firstIndex(where: {$0 == "A"})
Exemplo2
if let i = alphabets.firstIndex(of: "E") {
alphabets[i] = "C" // i is the index
}
print(alphabets)
// Prints "["A", "B", "C", "D"]"
Enquanto indexOf()
funciona perfeitamente, ele retorna apenas um índice.
Eu estava procurando uma maneira elegante de obter uma matriz de índices para elementos que satisfazem alguma condição.
Aqui está como isso pode ser feito:
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 classe personalizada, você precisa implementar o 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)
Atualização para o Swift 2:
sequence.contains (elemento) : retorna true se uma determinada sequência (como uma matriz) contiver o elemento especificado.
Swift 1:
Se você está olhando apenas para verificar se um elemento está contido em uma matriz, ou seja, obtenha um indicador booleano, use em contains(sequence, element)
vez de find(array, element)
:
contém (sequência, elemento) : retorna true se uma determinada sequência (como uma matriz) contiver o elemento especificado.
Veja o exemplo abaixo:
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.
}
no Swift 4.2
.index (where :) foi alterado para .firstIndex (where :)
array.firstIndex(where: {$0 == "person1"})
Swift 4. Se sua matriz contiver elementos do tipo [String: AnyObject]. Então, para encontrar o índice do elemento, use o código abaixo
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)
Ou Se você deseja encontrar o índice com base na chave do Dicionário. Aqui a matriz contém objetos da classe Model e eu estou correspondendo a propriedade 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
? O uso de self
é questionável também.
No Swift 4 , se você estiver percorrendo sua matriz DataModel, verifique se o modelo de dados está em conformidade com o Equatable Protocol, implemente o método lhs = rhs e somente então você poderá usar ".index (of". Por exemplo
class Photo : Equatable{
var imageURL: URL?
init(imageURL: URL){
self.imageURL = imageURL
}
static func == (lhs: Photo, rhs: Photo) -> Bool{
return lhs.imageURL == rhs.imageURL
}
}
E depois,
let index = self.photos.index(of: aPhoto)
No Swift 2 (com o Xcode 7), Array
inclui um indexOf
método fornecido pelo CollectionType
protocolo. (Na verdade, dois indexOf
métodos - um que usa igualdade para combinar com um argumento e outro que usa um fechamento.)
Antes do Swift 2, não havia uma maneira de tipos genéricos, como coleções, fornecerem métodos para os tipos concretos derivados deles (como matrizes). Então, no Swift 1.x, "índice de" é uma função global ... E também foi renomeada, portanto, no Swift 1.x, essa função global é chamada find
.
Também é possível (mas não necessário) usar o indexOfObject
método de NSArray
... ou qualquer outro método de pesquisa mais sofisticado da Foundation que não tenha equivalentes na biblioteca padrão do Swift. Apenas import Foundation
(ou outro módulo que importa transitivamente o Foundation), faça a conversão Array
para NSArray
e você poderá usar os vários métodos de pesquisa NSArray
.
Qualquer uma dessas soluções funciona para mim
Esta é a solução que tenho para o 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
})
Você também pode usar a biblioteca funcional Dollar para executar um indexOf em uma matriz como tal http://www.dollarswift.org/#indexof-indexof
$.indexOf([1, 2, 3, 1, 2, 3], value: 2)
=> 1
Se você ainda estiver trabalhando no Swift 1.x
Então tente,
let testArray = ["A","B","C"]
let indexOfA = find(testArray, "A")
let indexOfB = find(testArray, "B")
let indexOfC = find(testArray, "C")
Para o SWIFT 3, você pode usar uma função simples
func find(objecToFind: String?) -> Int? {
for i in 0...arrayName.count {
if arrayName[i] == objectToFind {
return i
}
}
return nil
}
Isso fornecerá a posição numérica, para que você possa usar como
arrayName.remove(at: (find(objecToFind))!)
Espero ser útil
SWIFT 4
Digamos que você queira armazenar um número da matriz chamada cardButtons em cardNumber, você pode fazer o seguinte:
let cardNumber = cardButtons.index(of: sender)
remetente é o nome do seu botão
No Swift 4/5, use "firstIndex" para encontrar o índice.
let index = array.firstIndex{$0 == value}
Caso alguém tenha esse problema
Cannot invoke initializer for type 'Int' with an argument list of type '(Array<Element>.Index?)'
apenas faça isso
extension Int {
var toInt: Int {
return self
}
}
então
guard let finalIndex = index?.toInt else {
return false
}
Para (>= swift 4.0)
É bastante simples. Considere o seguinte Array
objeto.
var names: [String] = ["jack", "rose", "jill"]
Para obter o índice do elemento rose
, tudo o que você precisa fazer é:
names.index(of: "rose") // returns 1
Nota:
Array.index(of:)
retorna um Optional<Int>
.
nil
implica que o elemento não está presente na matriz.
Você pode querer desembrulhar o valor retornado ou usar um if-let
para contornar o opcional.