Сокращение, чтобы проверить, существует ли объект в массиве для Swift?

В настоящее время у меня есть массив таких объектов:

var myArr = [
  MyObject(name: "Abc", description: "Lorem ipsum 1."),
  MyObject(name: "Def", description: "Lorem ipsum 2."),
  MyObject(name: "Xyz", description: "Lorem ipsum 3.")
]

Я тестирую, если объект существует, прежде чем продолжить:

let item = myArr.filter { $0.name == "Def" }.first
if item != nil {
  // Do something...
}

Но я ищу более короткий способ сделать это, так как я делаю это много. Я хотел бы сделать что-то подобное, но это неверно:

if myArr.contains { $0.name == "Def" } {
  // Do something...
}

Есть ли сокращенный синтаксис, который у меня отсутствует, или лучший способ сделать это?

Ответ 1

Почему бы не использовать встроенную функцию contains()? Он поставляется в двух вариантах

func contains<S : SequenceType, L : BooleanType>(seq: S, predicate: @noescape (S.Generator.Element) -> L) -> Bool
func contains<S : SequenceType where S.Generator.Element : Equatable>(seq: S, x: S.Generator.Element) -> Bool

а первый принимает предикат как аргумент.

if contains(myArr, { $0.name == "Def" }) {
    println("yes")
}

Обновление: Начиная с Swift 2, и глобальные функции contains() имеют были заменены методами расширения протокола:

extension SequenceType where Generator.Element : Equatable {
    func contains(element: Self.Generator.Element) -> Bool
}

extension SequenceType {
    func contains(@noescape predicate: (Self.Generator.Element) -> Bool) -> Bool
}

а первый (предикат) используется как:

if myArr.contains( { $0.name == "Def" }) {
    print("yes")
}

Swift 3:

if myArr.contains(where: { $0.name == "Def" }) {
    print("yes")
}

Ответ 2

IMHO для достижения желаемого поведения вам нужно будет создать класс расширения для массива, который будет выглядеть примерно так:

extension Array {
    func contains(test: (T) -> Bool, action: (T) -> Void) {
        let filtered = self.filter(test)
        if(filtered.is​Empty) {
            action(filtered)
        }
    }
}

У меня нет xcode передо мной, поэтому я прошу прощения, если у меня есть синтаксическая ошибка. Однако, если вы используете часто, вы можете записать его следующим образом

myArr.contains({ $0.name == "Def"}) {
   // Do something...
}

Я бы переименовал его, чтобы предотвратить путаницу в вашем коде.