按最接近匹配项搜索Linq结果

6

我有一个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),删除匹配项,并将其附加到之前匹配的结果。然而,这似乎有点混乱,是否有更好的方法?谢谢 (注:仅使用名称进行搜索,不能使用SQL方法)

3个回答

10

你可以编写一个单独的函数,该函数接受名称和查询字符串,并返回整数值。

当你有了这个函数之后,只需通过order by返回:

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 子句进行排除。

谢谢,我刚刚测试了一下,看起来完美无缺。简单易懂 :) - Brap

7
你需要的是一种相似度评分函数。然后你可以这样做:
from s in userList
let score = Score(s, query)
where score > 80
orderby score descending
select s;

(假设评分函数给出0-100之间的值,其中100是完美匹配。)
现在从您的示例中不清楚评分函数应该是什么 - 这是您需要解决的问题 :)

谢谢你的帮助。我本来想用汉明距离方法,但对于这个问题来说可能有点过头和低效。 - Brap

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接