537 votes

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

J'essaie de trouver un item index en recherchant un list . Quelqu'un sait-il comment faire ?

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

937voto

sschuth Points 336

Comme swift est, à certains égards, plus fonctionnel qu'orienté objet (et que les tableaux sont des structures, et non des objets), utilisez la fonction "find" pour opérer sur le tableau, qui renvoie une valeur optionnelle, et soyez donc prêt à gérer une valeur nulle :

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

Utilisez firstIndex y lastIndex - selon que l'on recherche le premier ou le dernier indice de l'élément :

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

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

38 votes

Où avez-vous appris à connaître la fonction de recherche ? Je n'arrive pas à trouver de documentation sur la fonction "find" ou toute autre fonction globale.

17 votes

Venant du monde de la POO, comment suis-je censé trouver ce genre de fonctions flottantes ?

4 votes

Ils semblent être en grande partie sans papiers. Voir practicalswift.com/2014/06/14/ pour une liste (mais sachez que je n'ai pas vérifié si la liste est complète ou à jour).

90voto

gwcoffey Points 2444

Puedes 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 comprend votre élément en combinant ceux-ci :

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

Si vous voulez trouver la position, je ne vois pas de manière fantaisiste, 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 d'avoir un find méthode :

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

Maintenant, nous pouvons le faire :

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

0 votes

Pour le plaisir, j'ai ajouté un autre exemple où j'ai étendu la fonction intégrée Array d'avoir un find qui fait ce que vous voulez. Je ne sais pas encore si c'est une bonne pratique, mais c'est une expérience intéressante.

2 votes

Je veux juste signaler que vous devez utiliser ++idx comme indiqué dans la documentation : "À moins que vous n'ayez besoin du comportement spécifique de i++, il est recommandé d'utiliser ++i et --i dans tous les cas, car ils ont le comportement attendu typique consistant à modifier i et à renvoyer le résultat."

0 votes

Bon appel. Pendant que tu postais ça, je le révisais pour utiliser enumerate donc ça ne s'applique plus, mais vous avez tout à fait raison.

5voto

rickster Points 19870

En Swift 2 (avec Xcode 7), Array comprend un indexOf fournie par la méthode CollectionType protocole. (En fait, deux indexOf une méthode qui utilise l'égalité pour faire correspondre un argument, et un 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 qui en sont dérivés (comme les tableaux). Donc, dans Swift 1.x, "index of" est une fonction globale... Et elle a aussi été renommée, donc dans Swift 1.x, cette fonction globale s'appelle find .

Il est également possible (mais pas nécessaire) d'utiliser la fonction indexOfObject méthode de NSArray ... ou toute autre méthode de recherche plus sophistiquée de Foundation qui n'a pas d'équivalent dans la bibliothèque standard de Swift. Juste import Foundation (ou un autre module qui importe de manière transitive Foundation), intégrez votre module Array a NSArray et vous pouvez utiliser les nombreuses méthodes de recherche sur NSArray .

3voto

Encore PTL Points 1108

Vous pouvez également utiliser la bibliothèque fonctionnelle Dollar pour effectuer un indexOf sur un tableau comme suit http://www.dollarswift.org/#indexof-indexof

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

2voto

Nate Cook Points 4815

Utilisation de enumerate serait un moyen rapide :

let haystack = [1, 2, 3, 4, 5]
let needle = 2
var found:Int?

for (i, value) in enumerate(haystack) {
    if needle == value {
        found = i
    }
}
// found! is now 1

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X