我正在实现一个“搜索”自动完成。我想返回按用户提交的字符排序排序的结果列表,其中排序结果顶部的项是在第一个字符到n个字符中具有字符串中字符的项。
是否有一种使用LINQ的优雅方法来做到这一点?
例如,假设当用户键入“un”时,将从数据库返回以下项。
我想按以下方式返回所订购的结果以供显示:
请注意,对于“un”上面的每一个字符串,位置为1-2、7-8、10-11和11-12。
发布于 2012-07-15 19:21:05
一般来说,@HugoRune的答案是可行的,但存在两个问题,效率有点低。
ToLower()引导所有字符串首先转换为小写,即使第一个字符的比较表明它们不匹配。Contains(),一次是IndexOf()。所以我们穿过字符串两次。以下代码的效率至少是原来的两倍:
IEnumerable<string> stateNames= [your source here];
string searchString="un";
var result =
stateNames
.Select(state=> new {Name=state, Index = state.IndexOf(searchString, StringComparison.CurrentCultureIgnoreCase)})
.Where(tuple=>tuple.Index>=0)
.OrderBy(tuple=>tuple.Index)
.Select(tuple=>tuple.Name);发布于 2012-07-15 10:15:33
可以使用IndexOf获取子字符串的位置,并且可以在OrderBy子句中使用该索引。
(以下假设您有一个带有“Name”列的db表"States“)
var result = dc.States
.Where(s=>s.Name.ToLower().Contains("un"))
.OrderBy(s=>s.Name.ToLower().IndexOf("un"));或者一个简单的缓存解决方案,如果您不想每次访问db:
// call this once during initialisation
List<States> cachedStates =
dc.States.ToList();
...
// call this every time
var result = cachedStates
.Where(s=>s.Name.ToLower().Contains("un"))
.OrderBy(s=>s.Name.ToLower().IndexOf("un"));发布于 2012-07-15 06:22:17
我对实现自动完成功能的建议是,在应用程序加载和缓存中,以升序方式获取所有国家名称及其按名称排序的id。现在,每当您输入用户时,它都应该使用这个缓存结果集来匹配,使用linq查询。要获得更好的性能,另一个调整将是有最小的字符,例如,在您的情况下2,然后只执行linq查询。
以这种方式实现的原因:您只需按一次数据库就可以得到所有国家的名称,而不是每个字符上的键。请注意,您的国家更改不是每天都做的,所以您的缓存只能在应用程序重新启动时过期。
希望这能有所帮助
https://stackoverflow.com/questions/11489760
复制相似问题