在数组中查找对象?

Sah*_*bov 133 ios swift

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

我有一个类型的结构数组,T并想检查数组是否包含name属性等于的结构对象Foo.

试图用find()filter(),但他们只能用原始的类型,例如工作StringInt.引发一个关于不符合Equitable协议或类似内容的错误.

Dan*_*iel 247

SWIFT 3/4

检查元素是否存在

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

获取元素

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

获取元素及其偏移量

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

得到偏移量

if let fooOffset = array.firstIndex(where: {$0.name == "foo"}) {
    // do something with fooOffset
} else {
    // item could not be found
}
Run Code Online (Sandbox Code Playgroud)

  • 漂亮的Swift风格的答案! (6认同)
  • 谢谢你是我的救星,这已经清理了我的代码了很多 (4认同)
  • 这比 2020 年接受的答案对我帮助更大。 (2认同)

use*_*504 120

您可以使用谓词indexArray提供的方法(请参阅此处的Apple文档).

func index(where predicate: (Element) throws -> Bool) rethrows -> Int?
Run Code Online (Sandbox Code Playgroud)

对于您的具体示例,这将是:

Swift 3.0

if let i = array.firstIndex(where: { $0.name == "Foo" }) {
    return array[i]
}
Run Code Online (Sandbox Code Playgroud)

Swift 2.0

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

  • 仅限Swift 2.0? (3认同)
  • 是的,这只适用于swift 2.0.对不起应该提到它. (3认同)

rin*_*aro 83

FWIW,如果您不想使用自定义功能或扩展,您可以:

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

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

如果您有大阵列,您可能想要:

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

或者可能:

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

  • 从Swift 3.0开始,如果需要对象,可以使用:array.first(where:{$ 0.name =="Foo"}) (71认同)
  • 从Swift 2.0开始,您可以使用:array.indexOf({$ 0.name =="Foo"}) (27认同)

Bre*_*ett 38

斯威夫特3

如果您需要使用对象:

array.first{$0.name == "Foo"}
Run Code Online (Sandbox Code Playgroud)

(如果你有多个名为"Foo" first的对象,那么将从未指定的顺序返回第一个对象)

  • 这很好,谢谢!也可以这样写:`array.first {$ 0.name =="Foo"}` (3认同)
  • 在**Swift3**中它必须是`array.first(where:{$ 0.name =="Foo"})` (2认同)

Muh*_*lah 20

斯威夫特2.1

现在,swift 2.1支持在对象属性中过滤.您可以根据结构或类的任何值过滤您的数组,这是一个示例

if let index = array.index(where: { $0.name == "Foo" }) {
    return array[index]
}
Run Code Online (Sandbox Code Playgroud)

要么

for myObj in myObjList where myObj.name == "foo" {
 //object with name is foo
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*n R 18

您可以过滤数组,然后只选择第一个元素,如在Array中使用Property属性查找对象中所示.

或者您定义自定义扩展

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

用法示例:

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

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

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


小智 8

斯威夫特3

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

func index(where predicate: @noescape Element throws -> Bool) rethrows -> Int?
Run Code Online (Sandbox Code Playgroud)

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


Pra*_*ore 7

斯威夫特4,

使用过滤功能实现此目的的另一种方法,

if let object = elements.filter({ $0.title == "title" }).first {
    print("found")
} else {
    print("not found")
}
Run Code Online (Sandbox Code Playgroud)