如何使用LINQ合并记录?

时间:2010-11-17 01:01:58

标签: c# linq

我想使用条件为行中的每个列合并两个记录。我会给你一个代码示例,但我不知道从哪里开始。

class Foo
{
    public int i {get;set;}
    public int b{get;set;}

    public string first{get;set;}
    public string last{get;set;}
    }

//...
    var list = new List<Foo>() { 
    new Foo () { i=1, b=0, first="Vince", last="P"},
    new Foo () { i=1, b=1, first="Vince", last="P"},
    new Foo () { i=1, b=0, first="Bob", last="Z"},
    new Foo () { i=0, b=1, first="Bob", last="Z"},
    } ;

// This is how I'd like my result to look like
// Record 1 - i = 1, b = 1, first="Vince", last = "P"
// Record 2 - i = 1, b = 1, first="Bob", last = "Z"

3 个答案:

答案 0 :(得分:1)

您可以对结果进行分组,然后汇总组中项目的字段:

var result = list.GroupBy(f => f.first).Select(
  g => new Foo() {
    b = g.Aggregate(0, (a, f) => a | f.b),
    i = g.Aggregate(0, (a, f) => a | f.i),
    first = g.Key,
    last = g.First().last
  }
);

答案 1 :(得分:0)

您可以在LINQ中使用Aggregate方法。

首先向Foo添加一个方法,说Merge根据合并规则返回一个新的Foo。

public Foo Merge (Foo other)
{
   // Implement merge rules here ...
   return new Foo {..., b=Math.Max(this.b, other,b), ...};

}

您也可以在Foo类之外创建一个辅助方法来进行合并。

现在在列表上使用Aggregate,使用第一个元素作为种子,将每个记录与当前聚合值合并。或者,而不是使用Aggregate(因为在这种情况下,它有点人为地使用LINQ),只需执行:

Foo result = list.First();
foreach (var item in list.Skip(1)) result = result.Merge(item);

您的合并规则是如何指定的?

答案 2 :(得分:0)

我找到了一个非常优雅的解决方案

var result = list.GroupBy(i=>i.first);
    foreach (IGrouping<string, Foo> grp in result)
    {
        grp.Aggregate ((f1, f2) => {

            return new Foo() {
                b = f1.b | f2.b,
                i = f1.i | f2.i,
                first = f1.first,
                last = f1.last
            };
        });
    }