【问题标题】:How to convert data using lambda expression or using any other logic?如何使用 lambda 表达式或任何其他逻辑转换数据?
【发布时间】:2011-06-17 04:00:42
【问题描述】:

我有一个包含这种格式数据的 DataTable。我想把它转换成另一种格式。 实现这一目标的最简单方法是什么?也许使用 lambda 表达式。我在用 C# 4.0

dattable1:
    seq     id        Amt
=============================
    1     00782       10 
    2     00782       20
    3     00782       30

    1     003850      40
    2     003850      50
    3     003850      60

    1     005723      70
    2     005723      80
    3     005723      90


To be stored in another datatable or list in this format

1  00782  003850  005723  10  40  70
2  00782  003850  005723  20  50  80
3  00782  003850  005723  30  60  90

示例 2

 dattable1:
        seq     id        Amt
    =============================
        1     00782       10 


        1     003850      40


        1     005723      70



    To be stored in another datatable or list in this format

    1  00782  003850  005723  10  40  70

【问题讨论】:

  • 你的新“格式”对我来说毫无意义。所以你只想将具有相同seq 的行放在一个新行中?他们会一直进三分吗?为什么需要它们采用这种“格式”?
  • 行数/列数总是一样吗?如果不是,每个序列值是否总是具有相同数量的条目?如果不是,将如何处理动态大小的输出行?
  • @jeff:因为我从参考游标(即存储过程)中获取这些数据。列数将保持不变,但行数可能会有所不同

标签: c# .net linq c#-4.0 linq-to-objects


【解决方案1】:

这将生成符合您要求的输入。

var datatable1 = new[]
{
    new { seq = 1, id = "00782", Amt = 10 }, 
    new { seq = 2, id = "00782", Amt = 20 }, 
    new { seq = 3, id = "00782", Amt = 30 }, 
    new { seq = 1, id = "003850", Amt = 40 }, 
    new { seq = 2, id = "003850", Amt = 50 }, 
    new { seq = 3, id = "003850", Amt = 60 }, 
    new { seq = 1, id = "005723", Amt = 70 }, 
    new { seq = 2, id = "005723", Amt = 80 }, 
    new { seq = 3, id = "005723", Amt = 90 }
};


var result = datatable1
    .GroupBy(arg => arg.seq)
    .Select(arg =>
        new
        {
            arg.Key,
            id1 = "00782",
            id2 = "003850",
            id3 = "005723",
            Amt1 = arg.Where(x => x.id == "00782").Sum(x => x.Amt),
            Amt2 = arg.Where(x => x.id == "003850").Sum(x => x.Amt),
            Amt3 = arg.Where(x => x.id == "005723").Sum(x => x.Amt),
        })
    .ToList();

[编辑]

对于“所有场景”:

var result = datatable1
    .GroupBy(arg => arg.seq)
    .Select(arg =>
        new
        {
            arg.Key,
            Ids = arg.Select(x => x.id).ToList(),
            Amounts = arg.Select(x => x.Amt).ToList(),
        })
    .ToList();

foreach (var row in result)
    Console.WriteLine("{0}\t{1}\t{2}", row.Key, string.Join("\t", row.Ids), string.Join("\t", row.Amounts));

输出:

1       00782   003850  005723  10      40      70
2       00782   003850  005723  20      50      80
3       00782   003850  005723  30      60      90

【讨论】:

  • @Alex Aza:+1 打败我!你的 id 不应该是动态的吗?即,从数据集中选择要使用的 id,而不是硬编码。
  • 谢谢你能进一步简化它,使它适用于所有场景,而不仅仅是这个
  • @Ulhas Tuscano:您能定义问题中的所有场景吗?目前还不清楚哪些变量可能是动态的,哪些不是。也许添加另外两个示例来展示不同的可能性会有所帮助。
  • @Alex 我又添加了一个示例,行数可能因条件而异
  • 如果行数不同,除非我误解了原始问题,否则将不起作用。 (我应该说 ID 的数量不同。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多