在数组中查找具有属性的对象

时间:2014-09-27 09:44:58

标签: ios swift

是否有可能从具有特定属性的数组中获取对象?或者我是否需要循环遍历我的数组中的所有对象并检查属性是否是我正在寻找的特定属性?

编辑:感谢您给我正确的方向,但我有一个问题要转换它。

//再次编辑:好的,如果只有一个特定的结果?这也是一种可行的方法吗?

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

5 个答案:

答案 0 :(得分:109)

  

//这不起作用 - NSArray不是图像的子类型 - 那么如果只有一个可能的结果呢?

您无法在编译时证明阵列上只有一个可能的结果。您实际要求的是第一个匹配结果。最简单的(虽然不是最快)只是取过滤结果的第一个元素:

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

imageObject现在将是一个可选项,因为它可能没有任何匹配。

如果搜索整个数组非常耗时,当然你可以轻松地创建一个firstMatching函数,该函数将返回与闭包匹配的(可选)第一个元素,但对于短数组,这很简单。


正如查尔斯所说,在Swift 3中,这是内置的:

questionImageObjects.first(where: { $0.imageUUID == imageUUID })

答案 1 :(得分: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})

答案 2 :(得分: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返回一个包含满足逻辑表达式的所有项的数组。

Library Reference

中的更多信息

答案 3 :(得分:6)

以下是 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}

参考: Trailing Closure

答案 4 :(得分:3)

这是通过使用object属性搜索数组中的对象来获取特定对象的其他方法。

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