我有一个 List<Locations>
将被过滤以产生一组与搜索词相关的结果。
目前,我通过以下过滤尝试了这些“搜索结果”:
return locations.Where(o => o.Name.Contains(term)).Take(10).ToList();
问题
如果我输入“Chester”作为搜索词,我将永远不会看到项目“Chester”,尽管它存在于 locations
中。列表。原因是列表中有 10 个或更多其他项目的名称中包含字符串“Chester”(Manchester、Dorchester 等)。
我如何使用 LINQ 首先获取以搜索词开头的结果?
到目前为止我得到了什么
var startsWithList = list.Where(o => o.Name.StartsWith(term)).Take(10).ToList();
var containsList = list.Where(o => o.Name.StartsWith(term) && !startsWithList.Contains(o)).Take(10 - startsWithList.Count).ToList();
return startsWithList.AddRange(containsList);
我一点都不喜欢上面的代码。我觉得这应该一次实现 Where
而不是执行两个 Where 和 Take 并组合两个列表。
最佳答案
只需在 Take 之前按升序排列,为以 term 开头的项目设置较低的值。
return locations.Where(o => o.Name.Contains(term))
.OrderBy(m => m.Name.StartsWith(term) ? 0 : 1)
//or OrderByDescending(m => m.Name.StartsWith(term))
.Take(10)
.ToList();
适应了MikeT的改进(StartsWith之前的精确匹配),你可以这样做
return locations.Where(o => o.Name.Contains(term))
.OrderBy(m => m.Name.StartsWith(term)
? (m.Name == term ? 0 : 1)
: 2)
.Take(10)
.ToList();
关于c# - 使用 LINQ Where/Take 返回最相关的搜索结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19569441/