Swift过滤嵌套数组

时间:2016-09-20 13:24:52

标签: ios swift nsmutablearray

我有一个NSMutableArray,它自己里面有很多数组。在所有索引的每个数组中,他们还有下面给出的类的自定义对象。

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

我想针对两个对象过滤这个嵌套数组。 例如,如果用户在searchBar中键入一些文本,并检查该嵌套数组中的文本,如果该文本与name或userName或两者匹配。

5 个答案:

答案 0 :(得分:4)

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

这是一种纯函数式方法,可以生成一个新的嵌套数组,该数组只包含具有匹配用户的数组,这些数组也只包含匹配的用户。

答案 1 :(得分:3)

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")
        }
    }

}

答案 2 :(得分:2)

一些建议

结构更适合模型值

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)数组,其中nameusername包含keyword

答案 3 :(得分:1)

使用filter(_:)提供的Array方法,这是一种更“快捷”的方法。

方法:

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!")
        }
    }

答案 4 :(得分:1)

matteok建议的稍有改进的版本:

在这种过滤中忽略寄存器是有意义的,而不是检查相等性检查查找目标是否包含搜索查询

使用!$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 }