使用LINQ Where/Take返回最相关的搜索结果

2 c# linq list .net-4.0 where

我有一个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并将两个列表组合在一起.

Rap*_*aus 8

只需在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)