[0, 2, 4] i...">

Swift - How to get indexes of filtered array elements

let items: [String] = ["A", "B", "A", "C", "A", "D"] items.whatFunction("A") // -> [0, 2, 4] items.whatFunction("B") // -> [1] 

Does Swift 3 support a function like whatFunction(_: Element) ?

If not, what is the most efficient logic?

+12
arrays swift swift3 swift4
source share
7 answers

You can create your own extension for arrays.

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

You can simply call it like this

 items.indexes(of: "A") // [0, 2, 4] items.indexes(of: "B") // [1] 
+11
source share

You can directly filter the indices array, this eliminates the extra map ping.

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

or as an extension of 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] 

or even more general

 extension Collection where Element: Equatable { func whatFunction(_ value : Element) -> [Index] { return self.indices.filter {self[$0] == value} } } 
+17
source share

You can achieve this with the chain:

  1. enumerated() - add indexes;
  2. filter() unnecessary elements;
  3. map() our indices.

Example (works in 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] 

Another way is to use flatMap , which allows you to check the element and return the index, if necessary, in one closure.

Example (works in Swift 3 - Swift 4.0 ):

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

But starting with Swift 4.1, flatMap which can return objects other than nil, is deprecated, and you should use compactMap .

Example (works with Swift 4.1 ):

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

And the cleanest and cheapest way is to iterate over the indexes of the array and check if the array element in the current index is equal to the required element.

Example (works in Swift 3 - Swift 4.x ):

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

In Swift 3 and Swift 4, you can do this:

 let items: [String] = ["A", "B", "A", "C", "A", "D"] extension Array where Element: Equatable { func indexes(of item: Element) -> [Int] { return enumerated().compactMap { $0.element == item ? $0.offset : nil } } } items.indexes(of: "A") 

I hope my answer was helpful 😊

+8
source share

you can use it like this:

  let items: [String] = ["A", "B", "A", "C", "A", "D"] let indexes = items.enumerated().filter { $0.element == "A" }.map{$0.offset} print(indexes) 
+2
source share

just copy and paste

 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
source share

For example, searching for indices of p_last values ​​in an inds1 array: (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
source share

All Articles