web-dev-qa-db-fra.com

Comment trouver l'index d'un élément de la liste dans Swift?

J'essaie de trouver un index d'articles en recherchant une liste. Est-ce que quelqu'un sait comment faire ça?

Je vois qu'il y a list.StartIndex et list.EndIndex mais je veux quelque chose comme le list.index("text") de python.

413
Chéyo

Comme Swift est à certains égards plus fonctionnel que l’objet orienté (et que les tableaux sont des structures, pas des objets), utilisez la fonction "find" pour agir sur le tableau, ce qui retourne une valeur optionnelle. gérer une valeur nulle:

let arr:Array = ["a","b","c"]
find(arr, "c")!              // 2
find(arr, "d")               // nil

Mise à jour pour Swift 2.0:

L'ancienne fonction find n'est plus supportée avec Swift 2.0!

Avec Swift 2.0, Array permet de rechercher l'index d'un élément à l'aide d'une fonction définie dans une extension de CollectionType (que Array implémente):

let arr = ["a","b","c"]

let indexOfA = arr.indexOf("a") // 0
let indexOfB = arr.indexOf("b") // 1
let indexOfD = arr.indexOf("d") // nil

De plus, la recherche du premier élément d'un tableau remplissant un prédicat est prise en charge par une autre extension 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

Notez que ces deux fonctions renvoient des valeurs optionnelles, comme find.

Mise à jour pour Swift 3.0:

Notez que la syntaxe de indexOf a changé. Pour les articles conformes à Equatable, vous pouvez utiliser:

let indexOfA = arr.index(of: "a")

Une documentation détaillée de la méthode est disponible à l’adresse suivante: https://developer.Apple.com/reference/Swift/array/1689674-index

Pour les éléments de tableau non conformes à Equatable, vous devrez utiliser index(where:):

let index = cells.index(where: { (item) -> Bool in
  item.foo == 42 // test if this is the item you're looking for
})

Mise à jour pour Swift 4.2:

Avec Swift 4.2, index n'est plus utilisé, mais est séparé en firstIndex et lastIndex pour une meilleure clarification. Donc, selon que vous recherchiez le premier ou le dernier index de l’article:

let arr = ["a","b","c","a"]

let indexOfA = arr.firstIndex(of: "a") // 0
let indexOfB = arr.lastIndex(of: "a") // 3
777
sschuth

tl; dr:

Pour les cours, vous recherchez peut-être:

let index = someArray.firstIndex{$0 === someObject}

Réponse complète:

Je pense qu'il vaut la peine de mentionner qu'avec les types de référence (class), vous pouvez effectuer une comparaison d'identité , auquel cas vous devez simplement utilisez l'opérateur d'identité === dans la fermeture du prédicat:


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

Notez que la syntaxe ci-dessus utilise la syntaxe de fermeture finale et équivaut à:

let indexOfPerson1 = people.firstIndex(where: {$0 === person1})


Swift 4/Swift 3 - cette fonction s'appelait auparavant index

Swift 2 - la fonction s'appelait auparavant indexOf

* Notez le pertinent et utile commentaire par paulbailey à propos de class types qui implémentent Equatable, où vous devez envisager la possibilité de comparer en utilisant === (( opérateur d'identité ) ou == ( égalité opérateur). Si vous décidez de faire correspondre en utilisant ==, alors vous pouvez simplement utiliser la méthode suggérée par d'autres (people.firstIndex(of: person1)).

186

Vous pouvez filter un tableau avec une fermeture:

var myList = [1, 2, 3, 4]
var filtered = myList.filter { $0 == 3 }  // <= returns [3]

Et vous pouvez compter un tableau:

filtered.count // <= returns 1

Ainsi, vous pouvez déterminer si un tableau inclut votre élément en combinant ces éléments:

myList.filter { $0 == 3 }.count > 0  // <= returns true if the array includes 3

Si vous voulez trouver le poste, je ne vois pas les moyens fantaisistes, mais vous pouvez certainement le faire comme ceci:

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
    }
}

EDIT

Pendant que nous y sommes, pour un exercice amusant, étendons Array pour avoir une méthode find:

extension Array {
    func find(includedElement: T -> Bool) -> Int? {
        for (idx, element) in enumerate(self) {
            if includedElement(element) {
                return idx
            }
        }
        return nil
    }
}

Maintenant nous pouvons faire ceci:

myList.find { $0 == 3 }
// returns the index position of 3 or nil if not found
80
gwcoffey

Swift 5

func firstIndex(of element: Element) -> Int?

var alphabets = ["A", "B", "E", "D"]

Exemple 1

let index = alphabets.firstIndex(where: {$0 == "A"})

Exemple2

if let i = alphabets.firstIndex(of: "E") {
    alphabets[i] = "C" // i is the index
}
print(alphabets)
// Prints "["A", "B", "C", "D"]"
29
Saranjith

Bien que indexOf() fonctionne parfaitement, il ne retourne qu'un index.

Je recherchais un moyen élégant d’obtenir un tableau d’index pour des éléments satisfaisant certaines conditions.

Voici comment cela peut être fait:

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)
23
Serhii Yakovenko

Pour la classe personnalisée, vous devez implémenter le protocole 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)
12
ZYiOS

Mise à jour pour Swift 2:

sequence.contains (element): Renvoie true si une séquence donnée (telle qu'un tableau) contient l'élément spécifié.

Swift 1:

Si vous cherchez seulement à vérifier si un élément est contenu dans un tableau, c’est-à-dire, obtenez un indicateur booléen, utilisez contains(sequence, element) au lieu de find(array, element):

contient (sequence, element): Renvoie true si une séquence donnée (telle qu'un tableau) contient l'élément spécifié.

Voir exemple ci-dessous:

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.   
}
9
Zorayr

Swift 4. Si votre tableau contient des éléments de type [String: AnyObject]. Donc, pour trouver l'index de l'élément, utilisez le code ci-dessous

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 si vous voulez trouver un index sur la base de la clé du dictionnaire. Ici, le tableau contient les objets de la classe Model et la propriété id correspondant.

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")
}
6
GSK

Toute cette solution fonctionne pour moi

C'est la solution que j'ai pour 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
        })
4
Kevin ABRIOUX

Dans Swift 4, si vous parcourez votre tableau DataModel, assurez-vous que votre modèle de données est conforme à Equatable Protocol, implémentez la méthode lhs = rhs et vous pourrez alors utiliser ".index (of"). Par exemple

class Photo : Equatable{
    var imageURL: URL?
    init(imageURL: URL){
        self.imageURL = imageURL
    }

    static func == (lhs: Photo, rhs: Photo) -> Bool{
        return lhs.imageURL == rhs.imageURL
    }
}

Puis,

let index = self.photos.index(of: aPhoto)
4
Naishta

Dans Swift 2 (avec Xcode 7), Array inclut une méthode indexOf fournie par le protocole CollectionType . (En fait, deux méthodes indexOf, l'une qui utilise l'égalité pour faire correspondre un argument et ne autre qui utilise une fermeture.)

Avant Swift 2, il n'existait aucun moyen pour les types génériques tels que les collections de fournir des méthodes pour les types concrets dérivés (tels que les tableaux). Ainsi, dans Swift 1.x, "index of" est une fonction globale ... Et il a également été renommé. Ainsi, dans Swift 1.x, cette fonction globale est appelée find.

Il est également possible (mais pas nécessaire) d’utiliser la méthode indexOfObject de NSArray... ou n’importe laquelle des méthodes de recherche plus sophistiquées de Foundation, qui n’ont pas d’équivalent dans la bibliothèque standard Swift. Juste import Foundation (ou un autre module qui importe transitoirement Foundation), transformez votre Array en NSArray et vous pouvez utiliser les nombreuses méthodes de recherche de NSArray.

4
rickster

Swift 2.1

var array = ["0","1","2","3"]

if let index = array.indexOf("1") {
   array.removeAtIndex(index)
}

print(array) // ["0","2","3"]

Swift

var array = ["0","1","2","3"]

if let index = array.index(of: "1") {
    array.remove(at: index)
}
array.remove(at: 1)
3
Luca Davanzo

Vous pouvez également utiliser la bibliothèque fonctionnelle Dollar pour créer un indexOf sur un tableau en tant que tel http://www.dollarswift.org/#indexof-indexof

$.indexOf([1, 2, 3, 1, 2, 3], value: 2) 
=> 1
2
Encore PTL

Si vous travaillez toujours dans Swift 1.x

alors essaye,

let testArray = ["A","B","C"]

let indexOfA = find(testArray, "A") 
let indexOfB = find(testArray, "B")
let indexOfC = find(testArray, "C")
2
iCyberPaul

Swift 4

Supposons que vous souhaitiez stocker un nombre du tableau appelé cardButtons dans cardNumber, vous pouvez le faire comme suit:

let cardNumber = cardButtons.index(of: sender)

l'expéditeur est le nom de votre bouton

1
Arturo

Swift 4

Pour les types de référence:

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
    }
}
0
Menno

Pour Swift 3, vous pouvez utiliser une fonction simple

func find(objecToFind: String?) -> Int? {
   for i in 0...arrayName.count {
      if arrayName[i] == objectToFind {
         return i
      }
   }
return nil
}

Cela donnera la position du numéro, de sorte que vous pouvez utiliser comme

arrayName.remove(at: (find(objecToFind))!)

J'espère être utile

0
Marco