我有一个List<Locations>将被过滤以产生一组与搜索词相关的结果.
目前,我通过以下过滤尝试了这些"搜索结果":
return locations.Where(o => o.Name.Contains(term)).Take(10).ToList();
Run Code Online (Sandbox Code Playgroud)
问题
如果我输入"切斯特"作为搜索词,我将永远不会看到项目"切斯特",尽管它存在于locations列表中.原因是列表中有10个或更多其他项目,其名称中包含字符串"Chester"(曼彻斯特,多切斯特等).
我怎样才能首先使用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);
Run Code Online (Sandbox Code Playgroud)
我根本不喜欢上面的代码.我觉得这应该在一个实现,Where而不是执行两个Where和Take并将两个列表组合在一起.
只需在Take之前按升序排序,为以item开头的项目设置较低的值.
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();
Run Code Online (Sandbox Code Playgroud)
适应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();
Run Code Online (Sandbox Code Playgroud)