Evgeniy Kleban
Evgeniy Kleban

Reputation: 6965

Swift return index of array element

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

Answers (3)

holex
holex

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

Connor Neville
Connor Neville

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

vadian
vadian

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

Related Questions