【问题标题】:Linq search result by closest match最接近匹配的 Linq 搜索结果
【发布时间】:2011-04-24 23:05:24
【问题描述】:

我有一个 ObservableCollection,它包含一个 Person 对象。我的应用程序中有一个搜索功能,并希望在顶部显示最相关的结果。这样做最有效的方法是什么?我当前的搜索方法只是调用contains 方法:

 var results = (from s in userList
               where s.Name.Contains(query)
               select s).ToList();

这很好用,但结果的排序顺序与它们在userList 中出现的顺序相同。如果我搜索Pete,那么它应该首先显示Pete,然后是Peter,然后是Peter Smith等等。 它不必太复杂,因为它只会处理几千个(最大)结果。我天真的方法是首先执行s.Name == query,显示该项目(如果有),然后执行s.Name.Contains(query),删除匹配的项目并将其附加到之前的匹配结果中。但是,这似乎有点到处都是,所以有更好的方法吗?谢谢 (ps - 搜索时只会使用名称,不能使用SQL方法)

【问题讨论】:

    标签: c# linq search windows-phone-7 observablecollection


    【解决方案1】:

    您可以创建一个提供名称和查询字符串并返回整数值的例程。

    购买后,只需通过以下方式退货:

    int QueryOrder(string query, string name)
    {
         if (name == query)
             return -1;
         if (name.Contains(query))
             return 0;
    
         return 1; 
    }
    

    然后做:

    var results = userList.OrderBy(s => QueryOrder(query, s.Name));
    

    这种方法的好处是,稍后,您可以扩展例程以提供更多详细信息,允许您根据收到的匹配“好”程度进行排序。例如,“Pete”->“Peter”可能比“Pete”->“Peter Smith”更匹配,所以你可以让你的逻辑为不同的选项返回不同的值......

    如果您需要删除“非 Pete”匹配项,也可以使用 Where 子句排除。

    【讨论】:

    • 谢谢,我刚刚对此进行了测试,它似乎工作得很好。很好很简单:)
    【解决方案2】:

    您需要某种相似度评分函数。然后你可以这样做:

    from s in userList
    let score = Score(s, query)
    where score > 80
    orderby score descending
    select s;
    

    (假设一个评分函数给出的值介于 0-100 之间,其中 100 是完美匹配。)

    现在从您的示例中不清楚确切应该是什么评分函数 - 那是由你来解决的 :)

    【讨论】:

    • 感谢您的帮助。我打算采用汉明距离方法,但对于这个问题,它可能有点矫枉过正且效率低下。
    【解决方案3】:
    var results = (from s in userList
                   where s.Name.Contains(query)
                   orderBy s.Length
                   select s).ToList();
    

    【讨论】:

      猜你喜欢
      • 2010-10-01
      • 2014-03-24
      • 2016-04-30
      • 1970-01-01
      • 1970-01-01
      • 2013-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多