2015-12-08 107 views
9

我从数据库Sytem.Collections.generic.IList获得通过searchText其过滤:排序列表对象

String searchText="E"; 
var query = something().List(); 
query = query.Where(x => !string.IsNullOrEmpty(x.Name) && 
x.Name.ContainsInsensitive(searchText)).ToList(); 
result = query.Select().ToList(); 

现在我想这个结果是由Name列进行排序。首先以searchText开头的所有值,然后是包含searchText的所有值。

如果我这样写:

result = result.OrderBy(x => x.Name).ToList(); 

我得到的结果是按名称进行排序,例如:这一切

1. "A name"  
2. "B name" 
3. "E name" 
4. "F name" 

包含Namee。我想,我的排序是:

1. "E name"  
2. "A name" 
3. "B name" 
4. "F name" 

我应该在我OrderBy表情的变化?

+1

我不认为这是可能的默认情况下。在字符串上排序的工作方式不同 –

+6

@AmitKumarGhosh - 默认情况下很少有可能“。这就是编程位进来的地方;) – Jamiec

+0

我跳过了'searchText'部分。是。真正。 –

回答

13

链一起2个订单OrderByThenBy

.OrderBy(x => x.Name.StartsWith(searchText) ? 0 : 1) 
.ThenBy(x => x.Name) 
+0

谢谢。有用。 – Simon

10

您可以接连做了两个排序电话(第一OrderBy,所有后续ThenBy):

result.OrderBy(x => !x.Name.StartsWith(searchText)).ThenBy(x => x.Name).ToList(); 

这将整理真(1)首先,然后(0)为假。 !x.Name使命令正确。然后它在两个组中排序x.Name

1

我觉得这是更准确:

result.OrderByDescending(x=>Regex.Split(x.Name, searchText, RegexOptions.IgnoreCase).Count()).ToList(); 

甚至更​​好:

result.OrderByDescending(x => 
    Regex.Split(x.Name, searchText, RegexOptions.IgnoreCase) 
    .Sum(el => el.StartsWith(searchText, StringComparison.InvariantCultureIgnoreCase) ? 1 : 0) 
).ToList(); 
+0

你为什么这么认为? –

+0

计算名称中存在searchText的次数 – csharpwinphonexaml

+0

那么为什么它更精确?按照OP的要求,它在哪里检查'开始'? –

3

那么,根据你的代码中有result物化List<T>

result = query.Select().ToList(); 

然后你是重建重新分配名单:

result = result.OrderBy(x => x.Name).ToList(); 

所以我建议整理in-place而不是OrderBy

result.Sort((x, y) => { 
    if (x.Name.StartsWith(searchText)) { 
     if (!y.Name.StartsWith(searchText)) 
     return 1; 
    } 
    else if (y.Name.StartsWith(searchText)) 
     return -1; 

    return String.Compare(x.Name, y.Name); 
    }); 
2

我想你关心的是搜索字符串的索引。所以与searchText相匹配的字符串将会成为第一个。这里是例子:

String searchText = "E"; 
List<string> result = new List<string> 
{ 
    "B name", 
    "A name", 
    "E name", 
    "FE name", 
}; 


result = result.OrderBy(x => x.IndexOf(searchText, StringComparison.OrdinalIgnoreCase)).ThenBy(x=>x).ToList(); 

你会得到

"E name", 
"FE name", 
"A name", 
"B name", 

但如果它不是你找什么,然后用StartsWith像在其他的答案。

+2

这是一个我还没有想到的好方法。问题是,它没有按预期对其余部分进行排序,因为'A'现在在'FE'之后排序。 –

+0

@PatrickHofman首先根据'searchText'排序。 '一个名字'在最后一个位置有'e',但'FE名'在第二个位置有'e',所以它在'A名字'之前成为' –

+0

我知道,但这可能不是OP所期望的。 –