C# 使用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

如何在LINQ忽略空字符串值的情况下对列值进行排序

现行订购守则

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();
}