簡體   English   中英

在數組中查找對象?

[英]Find an object in array?

Swift 在Underscore.js中有類似_.findWhere 的東西嗎?

我有一個T類型的結構數組,想檢查數組是否包含一個name屬性等於Foo的結構對象。

嘗試使用find()filter()但它們只適用於原始類型,例如StringInt 拋出關於不符合Equitable協議或類似內容的錯誤。

快速 5

檢查元素是否存在

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.firstIndex(where: {$0.name == "foo"}) {
    // do something with fooOffset
} else {
    // item could not be found
}

您可以將Array上可用的index方法與謂詞一起使用(請參閱此處的 Apple 文檔)。

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

對於您的具體示例,這將是:

斯威夫特 5.0

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

斯威夫特 3.0

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

斯威夫特 2.0

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

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

斯威夫特 3

如果您需要對象使用:

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

(如果您有多個名為“Foo”的對象,則first將從未指定的排序中返回第一個對象)

您可以過濾數組,然后只選擇第一個元素,如Find Object with Property in Array 所示

或者你定義一個自定義擴展

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
}

斯威夫特 3.0

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

斯威夫特 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
}

斯威夫特 4 ,

使用過濾器功能實現此目的的另一種方法,

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

斯威夫特 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 2 或更高版本

您可以組合indexOfmap以在一行中編寫“查找元素”函數。

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看起來很復雜,但是當找到數組中的第一個匹配項時,評估就停止了。 這兩種方法各有利弊。

訪問 array.index(of: Any) 的另一種方法是聲明您的對象

import Foundation
class Model: NSObject {  }

斯威夫特 3

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

使用contains

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

或者,您可以在評論中嘗試 Martin 指出的內容並再次嘗試filterFind Object with Property in Array

斯威夫特 3:

您可以使用 Swift 的內置功能在 Array 中查找自定義對象。

首先,您必須確保您的自定義對象符合: 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)
    }
}

將 Equatable 功能添加到您的對象后,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

對於 Swift 3,

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

對 Swift 使用Dollar ,它是 Lo-Dash 或 Underscore.js:

import Dollar

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

例如,如果我們有一個數字數組:

let numbers = [2, 4, 6, 8, 9, 10]

我們可以像這樣找到第一個奇數:

let firstOdd = numbers.index { $0 % 2 == 1 }

這將返回 4 作為可選整數,因為第一個奇數 (9) 位於索引 4。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM