0

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?

4
  • 1
    So to be clear, you want to filter an array where you only get elements of type T? Commented Nov 22, 2017 at 16:19
  • 1
    if you want to get back indices, why is the return value [T]? Commented Nov 22, 2017 at 16:20
  • @holex sorry i misstype, i did edit. Of course, i want indexes. Commented Nov 22, 2017 at 16:20
  • @vadian i want to pass class type, and dont wan't to pass Any. i want to pass concrete type. Commented Nov 22, 2017 at 16:26

3 Answers 3

3

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]
Sign up to request clarification or add additional context in comments.

3 Comments

@holex instead of that comment, you could have just pointed out my 1 typo
I have not debugged your code: just tested – then it failed.
Another alternative: self.enumerated().flatMap{ $0.element is T ? $0.offset : nil }
2

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 }
    }
}

1 Comment

indices.lazy.filter
1

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]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.