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

der*_*ida 51 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 } )
Run Code Online (Sandbox Code Playgroud)

Rob*_*ier 119

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

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

let imageObject = questionImageObjects.filter{ $0.imageUUID == imageUUID }.first
Run Code Online (Sandbox Code Playgroud)

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

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


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

questionImageObjects.first(where: { $0.imageUUID == imageUUID })
Run Code Online (Sandbox Code Playgroud)

  • 实际上,`questionImageObjects.first(其中:{$ 0.imageUUID == imageUUID})`可能就是使用swift 3的方式 (11认同)
  • 您可以在中间添加 `lazy` 函数,因此它应该只扫描数组到第一个匹配项,并避免您正确提到的性能问题:`let imageObject = questionImageObjects.lazy.filter{ $0.imageUUID == imageUUID }.first` (3认同)

nsc*_*hum 29

编辑2016-05-05: Swift 3将包含first(where:).

在Swift 2中,您可以使用indexOf查找与谓词匹配的第一个数组元素的索引.

let index = questionImageObjects.indexOf({$0.imageUUID == imageUUID})
Run Code Online (Sandbox Code Playgroud)

这比filter第一场比赛后停止要快一些.(或者,您可以使用lazy序列.)

但是,您只能获取索引而不是对象本身有点烦人.为方便起见,我使用以下扩展名:

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

然后以下工作:

questionImageObjects.find({$0.imageUUID == imageUUID})
Run Code Online (Sandbox Code Playgroud)


Ant*_*nio 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" } )
Run Code Online (Sandbox Code Playgroud)

请注意,filter返回一个包含满足逻辑表达式的所有项的数组.

" 库参考"中的更多信息


Kai*_* Ke 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}
Run Code Online (Sandbox Code Playgroud)

参考: 尾随闭包