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?
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] 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} } } You can achieve this with the chain:
enumerated()- add indexes;filter()unnecessary elements;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] 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 π
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) 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 } } 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]