在数组中find一个对象?
Swift在Underscore.js中有类似_.findWhere的东西吗?
我有一个T
types的结构数组,并希望检查数组是否包含name
属性等于Foo
的结构对象。
试图使用find()
和filter()
但它们只能用于基本types,例如String
或Int
。 抛出一个关于不符合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或更高版本
你可以结合indexOf
和map
来在一行中写一个“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