C# 在列表对象中排序
我从数据库C# 在列表对象中排序,c#,linq,C#,Linq,我从数据库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.
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"
所有这些都包含在Name
中的e
。我希望我的分类是:
1. "E name"
2. "A name"
3. "B name"
4. "F name"
我应该在我的
OrderBy
表达式中更改什么?用OrderBy
和然后用
.OrderBy(x => x.Name.StartsWith(searchText) ? 0 : 1)
.ThenBy(x => x.Name)
您可以依次执行两个排序调用(首先是OrderBy
,然后是所有后续的,然后是by
):
这将首先对true(1)进行排序,然后对false(0)进行排序。!x、 Name
使订单正确。然后它在两组中按x.Name
排序。我认为这更准确:
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();
那么,根据您的代码,您已经将结果
具体化为列表
:
然后重新创建并重新分配列表:
result = result.OrderBy(x => x.Name).ToList();
因此,我建议将排序方式改为就地排序,而不是按排序方式排序:
result.OrderBy(x => !x.Name.StartsWith(searchText)).ThenBy(x => x.Name).ToList();
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);
});
我想你关心的是搜索字符串的索引。因此,与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();
但是,如果这不是你想要的,那么像在其他答案中一样使用StartsWith
。我认为默认情况下这是不可能的。字符串排序differently@AmitKumarGhosh-几乎不可能“默认”。这就是编程位的作用;)我跳过了searchText
部分。对是的。那为什么它更准确呢?OP问它在哪里检查“以开头?”因为第二个单词可能以E开头,并且应该在第二个单词以A或任何其他字母开头的另一个项目之前。我认为你有点违反了要求!我写下了一个解决方案,它基于我如何在一个满是姓名的数据库中组织我的搜索。实际上,我要做的是通过给每个结果打分来确保正确的顺序,这是一个我还没有想到的好方法。问题是,它没有按预期对其余部分进行排序,因为A
现在在FE
之后排序。@PatrickHofman它首先根据searchText
进行排序A name
在最后一个位置有e
,但FE name
在第二个位置有e
,所以它在A name
之前,我知道,但这可能不是OP所期望的。
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",