Найти объект со свойством в массиве

ios swift

50007 просмотра

5 ответа

Есть ли возможность получить объект из массива с определенным свойством? Или мне нужно зациклить все объекты в моем массиве и проверить, является ли свойство именно тем, что я искал?

редактировать: спасибо, что дали мне в правильном направлении, но у меня есть проблема, чтобы преобразовать это.

// редактировать снова: хорошо, а если есть только один конкретный результат? Это также возможный способ сделать это?

let imageUUID = sender.imageUUID


let questionImageObjects = self.formImages[currentSelectedQuestion.qIndex] as [Images]!

    // this is working
    //var imageObject:Images!
    /*
    for (index, image) in enumerate(questionImageObjects) {

        if(image.imageUUID == imageUUID) {
            imageObject = image
        }

    }
    */

// this is not working - NSArray is not a subtype of Images- so what if there is only 1 possible result?
var imageObject = questionImageObjects.filter( { return $0.imageUUID == imageUUID } )
Автор: derdida Источник Размещён: 13.11.2019 11:34

Ответы (5)


116 плюса

Решение

// это не работает - NSArray не является подтипом Images- что, если есть только 1 возможный результат?

Вы не можете доказать во время компиляции, что в массиве есть только один возможный результат. То, что вы на самом деле просите, это первый соответствующий результат. Самый простой (хотя и не самый быстрый) - просто взять первый элемент результата фильтра:

let imageObject = questionImageObjects.filter{ $0.imageUUID == imageUUID }.first

imageObject теперь будет необязательным, конечно, так как возможно, что ничего не совпадает.

Если поиск по всему массиву занимает много времени, конечно, вы можете легко создать firstMatchingфункцию, которая будет возвращать (необязательный) первый элемент, соответствующий замыканию, но для коротких массивов это хорошо и просто.


Как отмечает Чарльз, в Swift 3 это встроено:

questionImageObjects.first(where: { $0.imageUUID == imageUUID })
Автор: Rob Napier Размещён: 27.09.2014 05:38

29 плюса

Редактировать 2016-05-05: Swift 3 будет включать first(where:).

В Swift 2 вы можете использовать, indexOfчтобы найти индекс первого элемента массива, который соответствует предикату.

let index = questionImageObjects.indexOf({$0.imageUUID == imageUUID})

Это немного быстрее по сравнению filterс тем, что он остановится после первого матча. (В качестве альтернативы вы можете использовать lazyпоследовательность.)

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

extension CollectionType {
    func find(@noescape predicate: (Self.Generator.Element) throws -> Bool) rethrows -> Self.Generator.Element? {
        return try indexOf(predicate).map({self[$0]})
    }
}

Тогда работает следующее:

questionImageObjects.find({$0.imageUUID == imageUUID})
Автор: nschum Размещён: 05.09.2015 07:30

10 плюса

Да, вы можете использовать filterметод, который принимает замыкание, где вы можете установить свое логическое выражение.

Пример:

struct User {
    var firstName: String?
    var lastName: String?
}

let users = [User(firstName: "John", lastName: "Doe"), User(firstName: "Bill", lastName: "Clinton"), User(firstName: "John", lastName: "Travolta")];

let johns = users.filter( { return $0.firstName == "John" } )

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

Больше информации в Библиотеке

Автор: Antonio Размещён: 27.09.2014 09:51

8 плюса

Вот рабочий пример в Swift 4

class Point{
    var x:Int
    var y:Int

    init(x:Int, y:Int){
        self.x = x
        self.y = y
    }
}

var p1 = Point(x:1, y:2)
var p2 = Point(x:2, y:3)
var p3 = Point(x:1, y:4)
var points = [p1, p2, p3]

// Find the first object with given property
let firstMatchingPoint = points.first{$0.x == 1}

// Find all objects with given property
let allMatchingPoints = points.filter{$0.x == 1}

Ссылка: Трейлинг Закрытие

Автор: Kai-jie Ke Размещён: 03.06.2017 07:13

3 плюса

Вот другой способ получить определенный объект, используя свойство объекта для поиска объекта в массиве.

if arrayTicketsListing.contains({ $0.status_id == "2" }) {
      let ticketStatusObj: TicketsStatusList = arrayTicketsListing[arrayTicketsListing.indexOf({ $0.status_id == "2" })!]
      print(ticketStatusObj.status_name)
}  

Принимая во внимание, что мой arrayTicketsListing [TicketsStatusList]содержит объекты TicketsStatusListкласса.

// TicketsStatusList class

class TicketsStatusList {
    internal var status_id: String
    internal var status_name: String
    init(){
        status_id = ""
        status_name = ""
    }
}
Автор: Kiran Jasvanee Размещён: 25.07.2016 06:16
Вопросы из категории :
32x32