C# 如何使用LINQ合并记录?

C# 如何使用LINQ合并记录?,c#,linq,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

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

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"
class-Foo
{
公共整数i{get;set;}
公共int b{get;set;}
第一个公共字符串{get;set;}
公共字符串last{get;set;}
}
//...
var list=新列表(){
newfoo(){i=1,b=0,first=“Vince”,last=“P”},
newfoo(){i=1,b=1,first=“Vince”,last=“P”},
newfoo(){i=1,b=0,first=“Bob”,last=“Z”},
newfoo(){i=0,b=1,first=“Bob”,last=“Z”},
} ;
//这就是我想要的结果
//记录1-i=1,b=1,first=“Vince”,last=“P”
//记录2-i=1,b=1,first=“Bob”,last=“Z”

您可以在LINQ中使用
聚合
方法

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

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

}
相反,您也可以在执行合并的Foo类之外创建一个helper方法

现在在列表上使用
Aggregate
,使用第一个元素作为种子,将每条记录与当前聚合值合并。或者,不要使用
Aggregate
(因为在本例中这是对LINQ的刻意使用),只需执行以下操作:

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

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

您可以在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类之外创建一个helper方法

现在在列表上使用
Aggregate
,使用第一个元素作为种子,将每条记录与当前聚合值合并。或者,不要使用
Aggregate
(因为在本例中这是对LINQ的刻意使用),只需执行以下操作:

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

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

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

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
            };
        });
    }
var result=list.GroupBy(i=>i.first);
foreach(结果中的IGrouping grp)
{
玻璃钢骨料((f1,f2)=>{
返回新的Foo(){
b=f1.b | f2.b,
i=f1.i | f2.i,
first=f1.first,
last=f1.last
};
});
}

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

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
            };
        });
    }
var result=list.GroupBy(i=>i.first);
foreach(结果中的IGrouping grp)
{
玻璃钢骨料((f1,f2)=>{
返回新的Foo(){
b=f1.b | f2.b,
i=f1.i | f2.i,
first=f1.first,
last=f1.last
};
});
}

您可以对结果进行分组,然后根据组中的项目聚合字段:

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

您可以对结果进行分组,然后根据组中的项目聚合字段:

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

那么,为了澄清,b所订购的每组Foo中,在字段i、first和last上匹配的最后一组?您希望以何种方式合并记录?结果看起来像是第二条记录,但仅仅选择其中一条记录并不涉及任何合并,因此应该如何确定结果?如果您注意到,b已合并为等于1。所以我想在b属性上执行AND操作。在大多数允许int充当布尔值0的语言中,1将是0。您的意思是“或”?对不起,是的,我的意思是或:-)那么,为了澄清,b订购的每组Foo中,在字段I、first和last上匹配的最后一组?您希望以何种方式合并记录?结果看起来像是第二条记录,但仅仅选择其中一条记录并不涉及任何合并,因此应该如何确定结果?如果您注意到,b已合并为等于1。所以我想在b属性上执行AND操作。在大多数允许int充当布尔值0的语言中,1将是0。你的意思是“或”?对不起,是的,我的意思是或:-)我想对b属性更新的答案执行更详细的OR操作。我想对b属性更新的答案执行更详细的OR操作。