Comment trouver l'index des éléments de liste dans Swift?

j'essaie de trouver un index d'articles en cherchant une liste. Quelqu'un sait comment faire cela?

je vois qu'il y a une liste.StartIndex et de la liste.EndIndex bu je veux quelque chose comme la liste de python.index("texte")

331
demandé sur Mick MacCallum 2014-06-04 08:10:41

16 réponses

comme swift est, à certains égards, plus fonctionnel que orienté objet (et les tableaux sont des structures, pas des objets), Utilisez la fonction "find" pour opérer sur le tableau, qui renvoie une valeur optionnelle, alors soyez prêt à traiter 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 par Swift 2.0!

avec Swift 2.0, Array gagne la capacité de trouver l'indice d'un élément en utilisant une fonction définie dans une extension de CollectionType (qui 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, trouver le premier élément dans un tableau remplissant un prédicat est supporté par une autre extension de CollectionType :

let arr2 = [1,2,3,4,5,6,7,8,9,10]
let indexOfFirstGreaterThanFive = arr2.indexOf({"151920920" > 5}) // 5
let indexOfFirstGreaterThanOneHundred = arr2.indexOf({"151920920" > 100}) // nil

notez que ces deux fonctions renvoient des valeurs optionnelles, comme find le faisait auparavant.

mise à jour pour Swift 3.0:

notez que la syntaxe d'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 peut être trouvée à https://developer.apple.com/reference/swift/array/1689674-index

pour les éléments de tableau qui ne se conforment pas à Equatable vous aurez besoin d'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 cherchez 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
638
répondu sschuth 2018-09-10 14:34:14

je pense qu'il est intéressant de mentionner qu'avec les types de référence ( class ) vous pourriez vouloir effectuer une identité comparaison, dans ce cas, vous avez juste besoin d'utiliser le === opérateur d'identité dans la fermeture prédicate:



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{"151900920" === person1} // 0
let indexOfPerson2 = people.index{"151900920" === person2} // 1
let indexOfPerson3 = people.index{"151900920" === person3} // 2
let indexOfPerson4 = people.index{"151900920" === person4} // nil

notez que la syntaxe ci-dessus utilise la syntaxe des fermetures à la traîne, et est équivalente à:

let indexOfPerson1 = people.index(where: {"151910920" === person1})



Swift 2 - la syntaxe de la fonction index utilisée pour être:

let indexOfPerson1 = people.indexOf{"151920920" === person1}



* Remarque pertinentes et utiles commentaire par paulbailey à propos de class les types qui mettent en œuvre des Equatable , où vous devez considérer si vous devez être en le comparant à l'aide de === ( identité opérateur) 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.index(of: person1) ).

141
répondu Nikolay Suvandzhiev 2018-01-11 11:30:26

Vous pouvez filter un tableau avec une fermeture:

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

Et vous pouvez compter un tableau:

filtered.count // <= returns 1

pour que vous puissiez déterminer si un tableau inclut votre élément en les combinant:

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

Si vous voulez trouver la position, je ne vois pas de fantaisie, 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 prolongeons 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 { "151950920" == 3 }
// returns the index position of 3 or nil if not found
77
répondu gwcoffey 2014-06-04 05:06:50

alors que indexOf() fonctionne parfaitement, il retourne seulement un index.

je cherchais un moyen élégant pour obtenir un tableau d'index pour les éléments qui satisfont à certaines conditions.

Ici est de savoir comment il peut être fait:

Swift 3:

let array = ["apple", "dog", "log"]

let indexes = array.enumerated().filter {
    "151900920".element.contains("og")
    }.map{"151900920".offset}

print(indexes)

Swift 2:

let array = ["apple", "dog", "log"]

let indexes = array.enumerate().filter {
    "151910920".element.containsString("og")
    }.map{"151910920".index}

print(indexes)
21
répondu Serhii Yakovenko 2016-09-14 07:30:18

pour la classe personnalisée, vous devez mettre en œuvre le protocole equable.

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
répondu ZYiOS 2015-11-16 06:27:10

mise à jour pour Swift 2:

de la séquence.contient(élément) : Renvoie true si une séquence donnée (comme un tableau) contient l'élément spécifié.

Swift 1:

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

contient (séquence, élément) : renvoie true si une séquence donnée (telle que 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
répondu Zorayr 2016-06-10 01:11:59

Swift 4.2

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

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

Exemple1

let index = alphabets.index(where: {"151910920" == "A"})

Exemple2

if let i = alphabets.index(of: "E") {
    alphabets[i] = "C" // i is the index
}
print(alphabets)
// Prints "["A", "B", "C", "D"]"
7
répondu Saranjith 2018-10-04 04:29:23

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

avant Swift 2, Il n'y avait pas de moyen pour les types génériques comme les collections de fournir des méthodes pour les types concrets dérivés de ceux-ci (comme tableau.) Donc, dans Swift 1.x, "index" est une fonction globale... Et il a été renommé, aussi, donc dans Swift 1.x, Cette fonction globale s'appelle find .

il est également possible (mais pas nécessaire) d'utiliser la méthode indexOfObject de NSArray ... ou l'une des autres méthodes de recherche plus sophistiquées de Foundation qui n'ont pas d'équivalents dans la bibliothèque standard Swift. Juste import Foundation (ou un autre module qui importe de façon transitoire la Fondation), Array à NSArray , et vous pouvez utiliser les nombreuses méthodes de recherche sur NSArray .

5
répondu rickster 2018-03-26 10:04:39

dans Swift 4 , si vous traversez votre tableau de DataModel, assurez-vous que votre modèle de données est conforme au Protocole equable , implémentez la méthode lhs=rhs , et seulement alors vous pouvez l'utiliser".index(de" . 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
    }
}

et puis,

let index = self.photos.index(of: aPhoto)
3
répondu Naishta 2017-11-22 06:11:50

vous pouvez également utiliser la bibliothèque fonctionnelle Dollar Pour faire un indexOf sur un tableau tel que http://www.dollarswift.org/#indexof-indexof

$.indexOf([1, 2, 3, 1, 2, 3], value: 2) 
=> 1
2
répondu Encore PTL 2014-11-10 00:25:30

si vous travaillez toujours dans Swift 1.x

alors essayer de,

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

let indexOfA = find(testArray, "A") 
let indexOfB = find(testArray, "B")
let indexOfC = find(testArray, "C")
2
répondu iCyberPaul 2015-07-20 12:54:57

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)
2
répondu Luca Davanzo 2017-07-11 12:38:33

L'une de ces solutions me convient

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
            "151900920" === tuesday
        })
2
répondu Kevin ABRIOUX 2018-07-24 06:32:09

Swift 4. Si votre tableau contient des éléments de type [String: AnyObject]. Donc, pour trouver l'index de l'élément utiliser 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 index sur la base de la clé du dictionnaire. Ici le tableau contient les objets de la classe Model et je suis 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")
}
1
répondu GSK 2018-02-08 10:36:40

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 nombre, de sorte que vous pouvez utiliser comme

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

espoir d'être utile

0
répondu Marco 2017-03-03 06:09:38

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
répondu Menno 2017-12-21 11:02:02