在数组中find一个对象?

Swift在Underscore.js中有类似_.findWhere的东西吗?

我有一个Ttypes的结构数组,并希望检查数组是否包含name属性等于Foo的结构对象。

试图使用find()filter()但它们只能用于基本types,例如StringInt 。 抛出一个关于不符合Equitable协议或类似的错误。

FWIW,如果你不想使用自定义函数或扩展,你可以:

 let array = [ .... ] if let found = find(array.map({ $0.name }), "Foo") { let obj = array[found] } 

这首先生成name数组,然后从中find

如果你有很多数组,你可能想要做:

 if let found = find(lazy(array).map({ $0.name }), "Foo") { let obj = array[found] } 

或者可能:

 if let found = find(lazy(array).map({ $0.name == "Foo" }), true) { let obj = array[found] } 

你可以用一个谓词来使用Array上可用的index方法( 参见这里的Apple文档 )。

 func index(where predicate: (Element) throws -> Bool) rethrows -> Int? 

对于你的具体例子,这将是:

Swift 3.0

 if let i = array.index(where: { $0.name == Foo }) { return array[i] } 

Swift 2.0

 if let i = array.indexOf({ $0.name == Foo }) { return array[i] } 

SWIFT 3/4

检查元素是否存在

 if array.contains(where: {$0.name == "foo"}) { // it exists, do something } else { //item could not be found } 

获取元素

 if let foo = array.first(where: {$0.name == "foo"}) { // do something with foo } else { // item could not be found } 

获取元素及其偏移量

 if let foo = array.enumerated().first(where: {$0.element.name == "foo"}) { // do something with foo.offset and foo.element } else { // item could not be found } 

获取偏移量

 if let fooOffset = array.index(where: {$0.name == "foo"}) { // do something with fooOffset } else { // item could not be found } 

Swift 3

如果您需要使用该对象:

 array.first{$0.name == "Foo"} 

(如果您有多个名为“Foo”的对象,则first会从未指定的顺序返回第一个对象)

Swift 2.1

在swift 2.1中现在支持在对象属性中进行过滤。 你可以根据结构或类的任何值来过滤你的数组,这里是一个例子

 for myObj in myObjList where myObj.name == "foo" { //object with name is foo } 

要么

 for myObj in myObjList where myObj.Id > 10 { //objects with Id is greater than 10 } 

您可以过滤数组,然后选取第一个元素,如“ 在数组中查找具有属性的对象”所示。

或者你定义一个自定义扩展

 extension Array { // Returns the first element satisfying the predicate, or `nil` // if there is no matching element. func findFirstMatching<L : BooleanType>(predicate: T -> L) -> T? { for item in self { if predicate(item) { return item // found } } return nil // not found } } 

用法示例:

 struct T { var name : String } let array = [T(name: "bar"), T(name: "baz"), T(name: "foo")] if let item = array.findFirstMatching( { $0.name == "foo" } ) { // item is the first matching array element } else { // not found } 

Swift 3中,您可以使用现有的first(where:)方法(如注释中所述 ):

 if let item = array.first(where: { $0.name == "foo" }) { // item is the first matching array element } else { // not found } 

Swift 3

你可以在Swift 3中使用index(where 🙂

 func index(where predicate: @noescape Element throws -> Bool) rethrows -> Int? 

 if let i = theArray.index(where: {$0.name == "Foo"}) { return theArray[i] } 

Swift 3

 if yourArray.contains(item) { //item found, do what you want } else{ //item not found yourArray.append(item) } 

Swift 2或更高版本

你可以结合indexOfmap来在一行中写一个“find element”函数。

 let array = [T(name: "foo"), T(name: "Foo"), T(name: "FOO")] let foundValue = array.indexOf { $0.name == "Foo" }.map { array[$0] } print(foundValue) // Prints "T(name: "Foo")" 

使用filter + first看起来更干净,但filter评估数组中的所有元素。 indexOf + map看起来很复杂,但是当数组中的第一个匹配被find时,评估停止。 这两种方法都有利有弊。

使用contains

 var yourItem:YourType! if contains(yourArray, item){ yourItem = item } 

或者你可以尝试一下Martin在注释中指出的内容,然后再试一次: 在数组中查找带有属性的对象 。

另一种访问array.index(of:Any)的方法是声明你的对象

 import Foundation class Model: NSObject { } 

对于Swift 3,

 let index = array.index(where: {$0.name == "foo"}) 

Swift使用Lo-Dash或Underscore.js的Dollar :

 import Dollar let found = $.find(array) { $0.name == "Foo" } 

Swift 3:

您可以使用内置的Swiftsfunction来查找数组中的自定义对象。

首先,您必须确保您的自定义对象符合: Equatable协议

 class Person : Equatable { //<--- Add Equatable protocol let name: String var age: Int init(name: String, age: Int) { self.name = name self.age = age } //Add Equatable functionality: static func == (lhs: Person, rhs: Person) -> Bool { return (lhs.name == rhs.name) } } 

将Equatablefunction添加到您的对象,Swift现在将显示您可以在数组上使用其他属性:

 //create new array and populate with objects: let p1 = Person(name: "Paul", age: 20) let p2 = Person(name: "Mike", age: 22) let p3 = Person(name: "Jane", age: 33) var people = [Person]([p1,p2,p3]) //find index by object: let index = people.index(of: p2)! //finds Index of Mike //remove item by index: people.remove(at: index) //removes Mike from array