“[NSManagedObject]”基于匹配字符串

时间:2016-07-09 19:18:22

标签: ios swift sorting nsmanagedobject predicate

我有一个[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


    }

任何想法我需要做什么?

1 个答案:

答案 0 :(得分:1)

正如@Sulthan所提到的,NSManagedObjects通常使用NSSortDescriptor进行排序,NSSortDescriptor在与NSFetchRequest一起使用时仅提供字母顺序。

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

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

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

  1. 计算查询与每个候选项之间的Levenshtein距离。粗略地说,Levenshtein距离是对一条弦与另一条弦的不同程度的测量。距离为0表示字符串相同。距离越大,琴弦越不同。
  2. 过滤掉Levenshtein距离与单词长度相同的候选者(意思是单词没有相似之处)
  3. 按Levenshtein距离订购结果。
  4. 以下是一个如何对字符串数组起作用的示例:

    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 ($0, levenshtein($0, bStr: query)) 
    }
    
    // Remove items which are completely different. 
    let filtered = proximity.filter() { 
        return $0.1 < $0.0.characters.count  
    }
    
    // Order items by proximity to the query.
    // This places close matches at the top.
    let sorted = filtered.sort() { 
        return $0.1 < $1.1 
    }
    
    // Filter tuples to return the data.
    let result = sorted.map() { 
        return $0.0 
    }
    
    print(result)
    

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