web-dev-qa-db-fra.com

Swift - Comment obtenir des index d'éléments filtrés d'un tableau

let items: [String] = ["A", "B", "A", "C", "A", "D"]

items.whatFunction("A") // -> [0, 2, 4]
items.whatFunction("B") // -> [1]

Swift 3 prend-il en charge une fonction telle que whatFunction(_: Element)?

Si non, quelle est la logique la plus efficace?

12
Byoth

Vous pouvez créer votre propre extension pour les tableaux.

extension Array where Element: Equatable {
    func indexes(of element: Element) -> [Int] {
        return self.enumerated().filter({ element == $0.element }).map({ $0.offset })
    }
}

Vous pouvez simplement l'appeler comme ça

items.indexes(of: "A") // [0, 2, 4]
items.indexes(of: "B") // [1]
9
Yannick

Vous pouvez filtrer la indices du tableau directement, cela évite la mapping supplémentaire.

let items = ["A", "B", "A", "C", "A", "D"]
let filteredIndices = items.indices.filter {items[$0] == "A"}

ou comme extension Array:

extension Array where Element: Equatable {

    func whatFunction(_ value :  Element) -> [Int] {
        return self.indices.filter {self[$0] == value}
    }

}

items.whatFunction("A") // -> [0, 2, 4]
items.whatFunction("B") // -> [1]

ou encore plus générique

extension Collection where Element: Equatable {

    func whatFunction(_ value :  Element) -> [Index] {
        return self.indices.filter {self[$0] == value}
    }

}
17
vadian

Vous pouvez y parvenir par la chaîne de:

  1. enumerated() - ajoute des index;
  2. filter() out items inutiles;
  3. map() nos index.

Exemple (fonctionne dans Swift 3 - Swift 4.x): 

let items: [String] = ["A", "B", "A", "C", "A", "D"]  
print(items.enumerated().filter({ $0.element == "A" }).map({ $0.offset })) // -> [0, 2, 4]

Une autre méthode consiste à utiliser flatMap, qui vous permet de vérifier l'élément et de renvoyer l'index si nécessaire dans une fermeture.

Exemple (fonctionne dans Swift 3 - Swift 4.0): 

print(items.enumerated().flatMap { $0.element == "A" ? $0.offset : nil }) // -> [0, 2, 4]

Mais depuis Swift 4.1, flatMap qui peut renvoyer des objets non nuls devient obsolète et vous devez plutôt utiliser compactMap .

Exemple (fonctionne depuis Swift 4.1): 

print(items.enumerated().compactMap { $0.element == "A" ? $0.offset : nil }) // -> [0, 2, 4]

Et le moyen le plus propre et le moins gourmand en mémoire consiste à parcourir le tableau indices et à vérifier si l’élément du tableau à l’index actuel est égal à l’élément requis.

Exemple (fonctionne dans Swift 3 - Swift 4.x): 

print(items.indices.filter({ items[$0] == "A" })) // -> [0, 2, 4]
8
pacification

Dans Swift 3 et Swift 4 vous pouvez le faire:

let items: [String] = ["A", "B", "A", "C", "A", "D"]

extension Array where Element: Equatable {

    func indexes(of item: Element) -> [Int]  {
        return enumerated().flatMap { $0.element == item ? $0.offset : nil }
    }
}

items.indexes(of: "A")

J'espère que ma réponse a été utile ????

8
Julien Kode

vous pouvez l'utiliser comme ça:

 let items: [String] = ["A", "B", "A", "C", "A", "D"]

        let indexes = items.enumerated().filter {
            $0.element == "A"
            }.map{$0.offset}

        print(indexes)
2
Abdelahad Darwish

il suffit de copier et coller

extension Array {
  func whatFunction(_ ids :  String) -> [Int] {

    var mutableArr = [Int]()
    for i in 0..<self.count {
        if ((self[i] as! String) == ids) {
            mutableArr.append(i)
        }
    }
        return mutableArr 
  }

}
1
sejal thesiya

Par exemple, recherche des indices des valeurs p_last figurant dans le tableau inds1: (Swift 4+)

let p_last = [51,42]
let inds1 = [1,3,51,42,4]
let idx1 = Array(inds1.filter{ p_last.contains($0) }.indices)

idx1 = [0,1]

0
bretcj7