Linq搜索结果最接近的匹配

时间:2010-10-13 16:28:31

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

我有一个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方法)

3 个答案:

答案 0 :(得分:10)

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

一旦你有了,只需通过以下方式返回:

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” - > “彼得”可能是比“皮特”更好的比赛 - > “彼得史密斯”,所以你可以让你的逻辑为不同的选项返回不同的值......

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

答案 1 :(得分:7)

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

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

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

现在从你的例子确切地开始并不清楚评分函数应该是什么 - 这是你可以解决的问题:)

答案 2 :(得分:0)

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