彼此没有相同值的C#Datatable排序列

时间:2018-12-06 16:55:32

标签: c# linq sorting datatable

我有如下所示的数据表输出,我试图以某种方式对行进行排序/排序,以使 包含test,test1,test2的列将不会互相重复。

基本上,我只想“混合”行,所以不会重复列的相同值(据可能)

图像显示了数据表Link to image中的21列中的4列

2 个答案:

答案 0 :(得分:0)

Rango的答案更为简洁,但是由于我从事过一个工作,因此它来了。您可以使用GroupBy对项目进行分组,然后循环将项目添加到每个组的新列表中:

static void Main(string[] args)
{
    var data = new List<string>
    {
        "test", "test", "test", "test", "test1", "test1",
        "test2", "test2", "test2", "test2", "test2", "test2",
    };

    var groups = data.GroupBy(x => x).OrderByDescending(x => x.Count());
    var maxGroupCount = groups.Max(g => g.Count());
    var orderedData = new List<string>();

    for (int i = 0; i < maxGroupCount; i++)
    {
        orderedData.AddRange(groups.Where(group => group.Count() > i)
            .Select(group => group.ElementAt(i)));
    }

    orderedData.ForEach(Console.WriteLine);

    GetKeyFromUser("\nDone! Press any key to exit...");
}

输出

enter image description here

答案 1 :(得分:0)

这里是使用LINQ对其进行处理的示例。这使用了Select的两个被遗忘的参数lambda版本来获取每个type的位置值。由于未显示任何列名,因此我将第一列称为type,而other列代表其余数据。

var db = new[] {
    new { type = "test", other = 1 },
    new { type = "test", other = 2 },
    new { type = "test", other = 3 },
    new { type = "test", other = 4 },
    new { type = "test1", other = 5 },
    new { type = "test1", other = 6 },
    new { type = "test2", other = 7 },
    new { type = "test2", other = 8 },
    new { type = "test2", other = 9 },
    new { type = "test2", other = 10 },
};

var ans = db.GroupBy(d => d.type)
            .Select(dg => dg.Select((d, i) => new { d, i }))
            .SelectMany(dig => dig)
            .GroupBy(di => di.i)
            .SelectMany(dig => dig.Select(di => di.d));

基本上,这是一个惯用语(现在我想要一个Schwartzian transform之类的很酷的名字),用于使IEnumerable<IEnumerable>>旋转,然后将其展平。

我创建了一种扩展方法来捕获关键的中心用法。

public static class IEnumerableIEnumerableExt {
    // Pivot IEnumerable<IEnumerable<T>> by grouping matching positions of each sub-IEnumerable<T>
    // src - source data
    public static IEnumerable<IEnumerable<T>> Pivot<T>(this IEnumerable<IEnumerable<T>> src) =>
        src.Select(sg => sg.Select((s, i) => new { s, i }))
            .SelectMany(sg => sg)
            .GroupBy(si => si.i)
            .Select(sig => sig.Select(si => si.s));

    public static DataTable ToDataTable(this IEnumerable<DataRow> src) {
        var ans = src.First().Table.Clone();
        foreach (var r in src)
            ans.ImportRow(r);
        return ans;
    }
}

使用这种扩展方法,答案变为:

var ans2 = db.GroupBy(d => d.type)
             .Pivot()
             .SelectMany(dg => dg);

如果来源是DataTable,则可以执行以下操作:

var ansdt = dt.AsEnumerable().GroupBy(r => r.Field<string>("type"))
              .Pivot()
              .SelectMany(rg => rg)
              .ToDataTable();

由于实际上没有一种简单的方法来对DataTable进行排序或排序,因此我添加了一种扩展方法,可以将IEnumerable<DataRow>转换为新的DataTable