Ios &引用;[NSManagedObject]”;基于匹配字符串的排序

Ios &引用;[NSManagedObject]”;基于匹配字符串的排序,ios,swift,sorting,nsmanagedobject,predicate,Ios,Swift,Sorting,Nsmanagedobject,Predicate,我有一个[NSManagedObject],我想根据最接近的匹配字符串进行排序 我已经研究过使用sortInPlace,但它看起来只会比较值并对它们进行排序 我还研究了使用谓词,但似乎无法在[NSManagedObject]上使用谓词 我正在尝试这个: if let query = searchController.searchBar.text { let predicate = NSPredicate(format: "title contains[c] %@", query)

我有一个[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提到的,NSManagedObject通常使用NSSortDescriptor进行排序,当与NSFetch请求一起使用时,它只提供字母顺序

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

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

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

  • 计算查询与每个候选对象之间的距离。粗略地说,Levenshtein距离是测量一根弦与另一根弦的不同程度。距离为0表示字符串相同。距离越远,弦的差异就越大
  • 过滤出Levenshtein距离与单词长度相同的候选词(意思是这些单词没有相似之处)
  • 按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 ($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)
    
    let data=[“海岸”、“秀”、“羊”、“商店”、“船”、“形状”、“海角”、“顶”、“帽”、“苹果”、“颈背”]
    let query=“ape”
    //计算每个项目与查询的匹配程度。
    //这将创建一个元组数组的形式(字,距离)。
    让邻近性=data.map(){
    返回($0,levenshtein($0,bStr:query))
    }
    //删除完全不同的项目。
    let filtered=approxity.filter(){
    返回$0.1<$0.0.characters.count
    }
    //按与查询的接近程度排序项目。
    //这将在顶部放置密切匹配。
    让sorted=filtered.sort(){
    返回0.1美元<1.1美元
    }
    //过滤元组以返回数据。
    让result=sorted.map(){
    返回$0.0
    }
    打印(结果)
    

    我用一个测试工具测试了这个例子。应该可以轻松地将其传输到NSManagedObject数组中进行排序。

    NSPredicate
    不用于排序。您需要一个
    NSSortDescriptor
    ,您必须创建最接近匹配求值的算法。
    NSSortDescriptor
    绝对不限于字母顺序。您可以使用它根据您可以编写代码的任何比较进行排序。@TomHarrington您在一般情况下是对的,尽管我指的是将NSSortDescriptor与NSFetchRequest一起使用,我假设询问者对此感兴趣,因为问题是关于NSManagedObjects的(澄清答案以反映这一点)。AFAIK不能在NSFetchRequest中使用带有排序描述符的任意代码,这将其限制为默认字符串比较器。如果我错了,请纠正我。没想到分拣会变得这么复杂。我会研究如何使用它,并在完成后给出反馈。我不能说它是完美的,但它确实有效。我做了一些小改动,使之与[NSManagedObject]一起工作。稍后可能会在github上发布代码