使用优先级过滤对象数组

时间:2016-09-06 13:25:04

标签: ios arrays swift filter

我试图过滤和排列一些人,并按特定顺序获取结果。这意味着当用户输入someString时,我想首先呈现他们的名字与someString匹配的人,然后从那个someString开始,之后包含那个字符串的任何名称。 我可以用Array" Filter"或者我必须在那之后进行另一种手动分类?

这是我的过滤代码:

static hash = StringHash::StaticHash("Hello"); // You may even use this expression in `switch case`

3 个答案:

答案 0 :(得分:1)

filter只能从集合中删除项目。它不能为您做任何订购操作。

您可能希望使用数组的单次传递来解决此问题,以便它可以正常运行。不要使用过滤器,而是做一些基本的事情:

var query = "test"

let allStrings = ["another test", "test", "testing", "random"]

var matchStrings = [String]()
var prefixStrings = [String]()
var containsStrings = [String]()

for str in allStrings {

    if query == str {
        matchStrings.append(str)
    } else if str.hasPrefix(query) {
        prefixStrings.append(str)
    } else if str.containsString(query) {
        containsStrings.append(str)
    }
}

let results = matchStrings + prefixStrings + containsStrings

答案 1 :(得分:0)

使用GROUP

sort

答案 2 :(得分:0)

您的代码与您的问题描述不符。我会按照您的描述进行操作,因为您的代码无法完成您想要的操作。

您可以为每场比赛打分并按匹配得分排序:

struct Person {
    var name: String
}

let names = [
    Person(name: "John Smith"),
    Person(name: "Alan Johnson"),
    Person(name: "Jane Doe"),
    Person(name: "John")
]

let searchText = "John".lowercaseString // take this from you search box

let filteredNames = names.flatMap { p -> (Person, Int)? in
    var score = 0
    let name = p.name.lowercaseString

    if name == searchText {
        score += 3
    } else if name.hasPrefix(searchText) {
        score += 2
    } else if name.containsString(searchText) {
        score += 1  
    }

    return score == 0 ? nil : (p, score)
}.sort { $0.1 > $1.1 }
 .map { $0.0 }

print(filteredNames) // John, John Smith, Alan Johnson

这是它的作用:

  • flatMap同时充当mapfilter。根据您的标准为每个人分配匹配的分数。如果匹配分数为0,我们会返回nil,因此flatMap将其排除。
  • sort按匹配分数
  • 对结果进行排序
  • map删除匹配的分数,以便最终的数组只包含Person

您可以将其扩展为电子邮件,电话号码等。只需围绕评分机制进行游戏。