C# 使用LINQ对列值排序忽略空字符串值
如何在LINQ忽略空字符串值的情况下对列值进行排序 现行订购守则C# 使用LINQ对列值排序忽略空字符串值,c#,asp.net,.net,linq,c#-4.0,C#,Asp.net,.net,Linq,C# 4.0,如何在LINQ忽略空字符串值的情况下对列值进行排序 现行订购守则 datatable.Select().OrderBy(u => u["ColName"]).ToArray(); 使用上述代码,首先列出空字符串值,然后是有序列表。 但是,我希望忽略空字符串值以使它们保持在相同的位置。如果它是一个sting列-datatable.Select()。其中(u=>!string.IsNullOrEmpty(u[“ColName”])).OrderBy(u=>u[“ColName”]).ToAr
datatable.Select().OrderBy(u => u["ColName"]).ToArray();
使用上述代码,首先列出空字符串值,然后是有序列表。
但是,我希望忽略空字符串值以使它们保持在相同的位置。如果它是一个sting列-
datatable.Select()。其中(u=>!string.IsNullOrEmpty(u[“ColName”])).OrderBy(u=>u[“ColName”]).ToArray()代码>试试这个
datatable.Select().OrderBy(u => !String.IsNullOrEmpty(u["ColName"]).ToArray();
提取不带空值的数组:{”、“2”、“2”、“1”、“4”、“3”}->{“2”、“1”、“4”、“3”}
对这一项进行排序:{“2”、“1”、“4”、“3”}->{“1”、“2”、“3”、“4”}
在旧列表中插入:{“1”、“2”、“3”、“4”}->{”、“1”、“1”、“2”、“3”、“4”}
val newArray=datatable.Select();
int orderedIndex=0;
for(int i=0;i
不是100%LINQ,但它应该可以工作您可以编写自己的(扩展)方法来进行此类排序(为简单起见,它用于数据行序列,但您可以使用相同的方法创建通用版本):
试验
输出
[
{ "Id": 1, "Name": "" },
{ "Id": 5, "Name": "a" },
{ "Id": 3, "Name": "" },
{ "Id": 2, "Name": "b" },
{ "Id": 4, "Name": "c" },
{ "Id": 6, "Name": "" }
]
试一试
//关于输入{”、“a”、“c”、“f”、“b”、“e”、“d”}
//关于输出{“a”、“a”、“b”、“c”、“d”、“e”、“f”}
公共静态列表排序(列表l)
{
过滤变量=l
.Select((s,i)=>new{i,s})
.Where(o=>!string.IsNullOrEmpty(o.s))
.OrderBy(o=>o.s)
.ToArray();
变量索引=过滤
.选择(o=>o.i)
.OrderBy(i=>i)
.Select((n,i)=>new{n,filtered[i].s})
.ToArray();
返回l
.选择((s,i)=>
{
if(string.IsNullOrEmpty)
返回s;
返回索引的.First(o=>o.n==i).s;
})
.ToList();
}
保持在同一位置意味着什么<代码>[“”,“b”、“”、“c”、“a”、“”]
应该变成[“”、“a”、“”、“b”、“c”、“”]
?最简单的方法是检查OrderBy
子句OrderBy(e=>!String.IsNullOrEmpty(u[“ColName”])中的空值或空值
@SergeyBerezovskiy,没错。提取所有空字符串的位置,排序,然后重新插入。自定义比较可以工作,但只是巧合,因为不可能以这种方式定义满足传递性规则的自定义比较。我正在将datatable内容导出到excel,因为中间有空行n、 我们需要在excel中显示在datatable中看到的空行。错误消息说“string.IsNullOrEmpty的最佳重载方法有一些无效参数”。我相信这将返回一个没有空值的列表。根据注释,OP希望包含空值。@JohnStephen-这是因为u[“ColName”]
是一个对象。IsNullOrEmpty
需要一个字符串
。您必须将作为字符串调用,ToString()
,或者以另一种方式将其设置为字符串。但如果它为null,请小心。问题是您需要调用u[“ColNAme”]。ToString(),因为string.IsNullOrEmpty需要字符串而不是对象。这将不会保留空值行的位置。我已更新了我的答案。谢谢。它按预期工作正常。
val ordered = toOrder.OrderBy(u => u["ColName"]);
val newArray = datatable.Select();
int orderedIndex = 0;
for(int i = 0; i < newArray.Count; i++)
{
if (newArray[i]["ColName"] != "")
{
newArray[i] = ordered[orderedIndex++];
}
}
public static IEnumerable<DataRow> SortByNonEmpty(
this IEnumerable<DataRow> source, string columnName)
{
var query = from r in source
let value = r.Field<string>(columnName)
where !String.IsNullOrEmpty(value)
orderby value
select r;
using (var ordinalEnumerator = source.GetEnumerator())
using (var sortedEnumerator = query.GetEnumerator())
{
while (ordinalEnumerator.MoveNext())
{
if (String.IsNullOrEmpty((ordinalEnumerator.Current.Field<string>(columnName))))
yield return ordinalEnumerator.Current;
sortedEnumerator.MoveNext();
yield return sortedEnumerator.Current;
}
}
}
datatable.AsEnumerable().SortByNonEmpty("ColName")
DataTable table = new DataTable();
table.Columns.Add("Id", typeof(int));
table.Columns.Add("Name", typeof(string));
table.Rows.Add(1, "");
table.Rows.Add(2, "b");
table.Rows.Add(3, "");
table.Rows.Add(4, "c");
table.Rows.Add(5, "a");
table.Rows.Add(6, "");
table.AsEnumerable().SortByNonEmpty("Name")
[
{ "Id": 1, "Name": "" },
{ "Id": 5, "Name": "a" },
{ "Id": 3, "Name": "" },
{ "Id": 2, "Name": "b" },
{ "Id": 4, "Name": "c" },
{ "Id": 6, "Name": "" }
]
var query = datatable.AsEnumerable(); // Or datatable.Select();
var sorted = query
.Where(u => (string) u["ColName"] != "")
.OrderBy(u => u["ColName"]).ToArray();
var idx = 0;
var results = query
.Select(u => (string) u["ColName"] == "" ? u : sorted[idx++]);
//On input { "", "a", "", "c", "f", "b", "", "e", "d" }
//On output { "", "a", "", "b", "c", "d", "", "e", "f" }
public static List<string> Sort(List<string> l)
{
var filtered = l
.Select((s, i) => new { i, s })
.Where(o => !string.IsNullOrEmpty(o.s))
.OrderBy(o => o.s)
.ToArray();
var indexed = filtered
.Select(o => o.i)
.OrderBy(i => i)
.Select((n, i) => new { n, filtered[i].s })
.ToArray();
return l
.Select((s, i) =>
{
if (string.IsNullOrEmpty(s))
return s;
return indexed.First(o => o.n == i).s;
})
.ToList();
}