Reputation: 6965
I want to write function that walk through array and return indexes where that element was found.
Something like:
extension Array {
func elementIndexes<T>() -> [Int] {
// if element is kind of class "T" add it to array [T] and then return
}
}
However, I have not succeeded. How can I do that?
Upvotes: 0
Views: 593
Reputation: 24031
this might work for you:
extension Array {
func indices<T>(of: T.Type) -> [Int] {
return self.enumerated().flatMap { $0.element is T ? $0.offset : nil }
}
}
or if you'd like dealing with more traditional solutions then this is your way:
extension Array {
func indices<T>(of: T.Type) -> [Int] {
var indices = [Int]()
for (n, item) in self.enumerated() {
if item is T {
indices.append(n)
}
}
return indices
}
}
like with this test array:
let array: [Any] = [1, 2, "3", "4"]
debugPrint(array.indices(of: String.self))
both presents the the same output in Playground, which is:
[2, 3]
Upvotes: 1
Reputation: 7361
It sounds, to clear up the wording, that you want to get all indices where the element is type T. Here's an extension on Array that'll do that, with an example:
extension Array {
func indices<T>(ofType type: T.Type) -> [Int] {
return self.enumerated().filter({ $0.element is T }).map({ $0.offset })
}
}
struct TypeA { }
struct TypeB { }
let list: [Any] = [TypeA(), TypeB(), TypeB(), TypeA()]
print(list.indices(ofType: TypeA.self)) // prints [0, 3]
Upvotes: 3
Reputation: 285240
You can filter the indices
directly, this is more generic version (credits to Leo Dabus
and Hamish
)
extension Collection {
func indices<T>(of type: T.Type) -> [Index] {
return indices.filter { self[$0] is T }
}
}
Upvotes: 2