簡體   English   中英

Swift 過濾器嵌套數組

[英]Swift Filter Nested Array

我有一個NSMutableArray ,它里面有很多數組。 在所有索引處的每個數組中,它們進一步具有下面給出的類的自定義對象。

Class User:NSObject{
    var name = ""
    var userName = ""
    var email = ""
    var age = 0
    var gender = ""
    var 
}

我想根據兩個對象過濾這個嵌套數組。 例如,如果用戶在 searchBar 中鍵入一些文本並檢查該嵌套數組中的文本,如果該文本與名稱或用戶名或兩者匹配。

let nestedArray: [[User]] = [[user1, user2], [user3], [user4, user5]]

let searchName = "foo"
let filteredArray = nestedArray.map({
        return $0.filter({ $0.name == searchName })
    }).filter({ $0.count > 0 })

這是一種純函數方式,它會產生一個新的嵌套數組,該數組僅包含具有匹配用戶的數組,並且這些數組也將僅包含匹配的用戶。

一些建議

結構體更適合模型值

struct User {
    let name: String
    let userName: String
    let email: String
    let age: Int
    let gender: String
}

不要使用 NSMutableArray

NSMutableArray是一個 Objective-C 類。 您可以通過 Swift 訪問它,但您應該使用 Swift 數組結構。 它更快,並且作為一種值類型,可以防止與訪問共享對象的代碼的多個部分相關的錯誤。

過濾數據

現在給定一組User數組

let data: [[User]] = ...

和一個關鍵字

let keyword: String = ...

你可以過濾你的數據寫入

let matchingUsers = data
    .flatMap { $0 }
    .filter { $0.name.range(of: keyword) != nil || $0.userName.range(of: keyword) != nil }

現在matchingUsers User(s)是一個User(s)數組,其中nameusername包含keyword

let textToSearch:String = "some text"

for nestedArray in myArray {

    for item:User in nestedArray
    {
        if user.name.contains(textToSearch) || user.userName.contains(textToSearch)
        {
            print("found")
        }
    }

}

這是使用Array提供的filter(_:)方法來執行此操作的更“快速”的方法。

方法:

func filter(_ isIncluded: (Element) throws -> Bool) rethrows -> [Element]

執行:

    // Create some generic objects to test on
    let object1 = User()
    object1.name = "John"
    object1.userName = "jdoe"

    let object2 = User()
    object2.name = "Jane"
    object2.userName = "jdoe"

    let object3 = User()
    object3.name = "Bob"
    object3.userName = "bjones"

    // Add them to a test array
    var objects = [[]]
    objects.append([object1])
    objects.append([object2])
    objects.append([object3])

    // What we want to search on
    let searchString = "j"

    // Filter the array
    for array in objects {
        let searchedSubArray = array.filter {
            return $0.name.rangeOfString(searchString, options: .CaseInsensitiveSearch)     != nil ||
                   $0.userName.rangeOfString(searchString, options: .CaseInsensitiveSearch) != nil

        }
        if (searchedSubArray.count > 0) {
            print("we found a match!")
        }
    }

matteok 建議的稍微改進的版本:

在這種過濾中忽略 register 是有意義的,而不是檢查查找目標是否包含搜索查詢的相等性檢查

同樣使用!$0.isEmpty比檢查$0.count > 0更快捷

let nestedArray: [[User]] = [[user1, user2], [user3], [user4, user5]]

let searchName = "foo".lowercased()
let filteredArray = nestedArray
  .map { $0.filter { $0.name.lowercased().contains(searchName) }}
  .filter { !$0.isEmpty }

暫無
暫無

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

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