开发者

How do I merge records using LINQ?

I'd like to merge two records using a condition for each column in the row. I'd give you a code sample but I don't know where to start.

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"


You can group the result, then aggregate the fields from the items in the group:

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


You could use the Aggregate method in LINQ.

First add a method to Foo, say Merge that returns a new Foo based on your merging rules.

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

}

You could also, instead, create a helper method outside the Foo class that does the merging.

Now use Aggregate over your list, using the first element as the seed, merging each record with the current aggregate value as you go. Or, instead of using Aggregate (since it's a somewhat contrived use of LINQ in this case), just do:

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

How are your merge rules specified?


I found a non-elegant solution that works

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜