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

ios swift

50007 просмотра

5 ответа

10097 Репутация автора

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

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

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

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 Источник Размещён: 27.09.2014 09:44

Ответы (5)


10 плюса

62016 Репутация автора

Да, вы можете использовать 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

116 плюса

217202 Репутация автора

Решение

// это не работает - 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 плюса

14256 Репутация автора

Редактировать 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

3 плюса

3488 Репутация автора

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

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

8 плюса

369 Репутация автора

Вот рабочий пример в 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
Вопросы из категории :
32x32