1

I have written my own small function to find an element in an array using a key. But I'm sure there is a ready to use implementation in Swift to get it in one line. Any hint?

func objectAtKey(array: [T], key: String) -> T? {
    for element in array {
        if element.name == key {
            return element
        }
    }
    return nil
}

I also know function indexOf, but this return an index, I have to use for further access. I think this is slower:

let index = array.indexOf({$0.name == key})

3 Answers 3

4

In Swift 3 (Xcode 8, currently beta 6) you can do

if let el = array.first(where: { $0.name == key }) {
    // `el` is the first array element satisfying the condition.
    // ...
} else {
    // No array element satisfies the condition.
}

using the first(where:) method of the Sequence protocol:

/// Returns the first element of the sequence that satisfies the given
/// predicate or nil if no such element is found.
///
/// - Parameter predicate: A closure that takes an element of the
///   sequence as its argument and returns a Boolean value indicating
///   whether the element is a match.
/// - Returns: The first match or `nil` if there was no match.
public func first(where predicate: (Element) throws -> Bool) rethrows -> Element?
Sign up to request clarification or add additional context in comments.

Comments

1

I think the best solution for you here is to use the indexOf with a Predicate that you have written. I would have written it like this though:

let array = ["Foo", "Bar", "Test"]
if let i = array.indexOf({$0 == "Foo"}) {
     print(array[i])
}

To handle if the value does not exists if you need that.

Comments

0

Try this:

let element = array.filter{ $0.name == key }.first

3 Comments

Yes, but this handles the entire array and takes the first element after doing all the work. I simply need the first (and only) matching element.
This unnecessarily iterates through every element – a better (pre Swift 3) solution would be to take advantage of a lazy collection instead, e.g let element = array.lazy.filter{ $0.name == key }.first – allowing it to stop iterating upon finding a match.
That sounds perfect. Thank you.

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.