使用LINQ对列值进行排序,忽略空字符串值

时间:2017-08-04 09:11:39

标签: c# asp.net .net linq c#-4.0

如何使用LINQ忽略空字符串值来对列值进行排序?

现有的订购代码

core module

使用上面的代码,首先列出空字符串值,然后是有序列表。 但是,我想忽略空字符串值以使它们保持在相同的位置。

6 个答案:

答案 0 :(得分:3)

尝试

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++]);

答案 1 :(得分:1)

试试这个

datatable.Select().OrderBy(u => !String.IsNullOrEmpty(u["ColName"]).ToArray();

答案 2 :(得分:0)

如果是刺痛栏 - url = r"file:///../Javascript/Main/TestApp/index-release.html"

答案 3 :(得分:0)

提取没有空值的数组:{ "", "2", "", "1", "4", "3" } -> { "2", "1", "4", "3" }

val toOrder = datatable.Select().Where(u => u["ColName"] != "");

对此进行排序:{ "2", "1", "4", "3" } -> { "1", "2", "3", "4" }

val ordered = toOrder.OrderBy(u => u["ColName"]);

插入旧列表:{ "1", "2", "3", "4" } -> { "", "1", "", "2", "3", "4" }

val newArray = datatable.Select();
int orderedIndex = 0;
for(int i = 0; i < newArray.Count; i++)
{
    if (newArray[i]["ColName"] != "")
    {
        newArray[i] = ordered[orderedIndex++];
    }
}

不是100%LINQ,但它应该有效

答案 4 :(得分:0)

您可以编写自己的(扩展)方法来执行此类排序(为简单起见,它是针对DataRows的序列,但您可以使用相同的方法创建通用版本):

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

它使用两个枚举器 - ordinalEnumerator枚举原始顺序的序列,sortedEnumerator枚举列中非空值的排序序列。即如果您将原始值视为["", "b","","c","a",""],则第一个枚举器将按原始顺序枚举所有元素。第二个枚举器只会生成元素["a","b","c"]

然后我们只检查源序列中的每个项目。如果列中有空值,那么我们只返回该行(从而保留空值的顺序)。否则我们从有序序列中取下一个项目。因此,非空值将按排序顺序排列。

用法:

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": "" }
]   

答案 5 :(得分:0)

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