“[NSManagedObject]” 根据匹配的字符串排序

"[NSManagedObject]" sort based on matching string

我有一个 [NSManagedObject],我想根据最接近的匹配字符串对其进行排序。

我研究过使用 sortInPlace,但看起来它只会比较值并对它们进行排序。

我也看过使用谓词,但我似乎无法在 [NSManagedObject] 上使用谓词。

我正在尝试这个:

if let query = searchController.searchBar.text {
       let predicate = NSPredicate(format: "title contains[c] %@", query)
        self.objects.//using predicate here doesn't work


    }

有什么想法吗??

如@Sulthan 所述,NSManagedObjects 通常使用 NSSortDescriptor 进行排序,当与 NSFetchRequest 一起使用时,它仅提供字母顺序。

还有其他方法可以按字符串接近程度对结果进行排序。通常这是使用预建索引完成的,其中每个 NSManagedObject 都是树或图中的一个节点。实现这样的索引并不过分复杂,但确实需要一些背景知识。

如果您的数据集不是太大,您可以将对象作为数组进行排序,如代码中所示。这里排序的一个关键要素是定义用于确定候选字符串与查询的匹配程度的规则。

一种方法是使用 Levenshtein 距离来计算匹配。其他匹配方式也可以,例如测量最长的匹配子串。

  1. 计算查询与每个候选之间的 Levenshtein 距离。 Levenshtein 距离粗略地说是衡量一个字符串与另一个字符串之间的差异程度。距离为 0 表示字符串相同。距离越大,字符串越不一样。
  2. 过滤掉 Levenshtein 距离与词长相同的候选词(意味着词没有相似之处)
  3. 按 Levenshtein 距离对结果排序。

这是一个示例,说明这可能如何处理字符串数组:

let data = ["shore", "show", "sheep", "shop", "ship", "shape", "cape", "cope", "cap", "apple", "nape"]

let query = "ape"

// Calculate how closely each item matches the query.
// This creates an array of tuples of the form (word, distance). 
let proximity = data.map() { 
    return ([=10=], levenshtein([=10=], bStr: query)) 
}

// Remove items which are completely different. 
let filtered = proximity.filter() { 
    return [=10=].1 < [=10=].0.characters.count  
}

// Order items by proximity to the query.
// This places close matches at the top.
let sorted = filtered.sort() { 
    return [=10=].1 < .1 
}

// Filter tuples to return the data.
let result = sorted.map() { 
    return [=10=].0 
}

print(result)

我用 Levenshtein implementation on GitHub 测试了这个例子。应该可以轻松地传输它来对 NSManagedObjects 数组进行排序。