2017-03-20 11 views
0

私は大量のデータ(〜130.000レコード)を扱っています。私はそれを(CSVへ)変換しています。LINQ - GroupBy複数の列を作成し、結果をマージする

:今、私はそうのような第一、第二と第三の列が一致し、あればレコードをマージしたい

"Surname1, Name1;Address1;State1;YES;Group1" 
"Surname2, Name2;Address2;State2;YES;Group2" 
"Surname2, Name2;Address2;State2;YES;Group1" 
"Surname3, Name3;Address3;State3;NO;Group1" 
"Surname1, Name1;Address2;State1;YES;Group1" 

:ここ

は、リストがどのように見えるかの簡単な例であります

出力

"Surname1, Name1;Address1;State1;YES;Group1" 
"Surname2, Name2;Address2;State2;YES;Group2 Group1" 
"Surname3, Name3;Address3;State3;NO;Group1" 
"Surname1, Name1;Address2;State1;YES;Group1" 
01ここ

は、私がこれまで持っているものです:

var query= from r in output 
      let columns= r.Split(';') 
      select new { c1 =columns[0], c2 =columns[1], c3 = columns[2] ,c5=columns[4]}; 

そしてグループを作成しますが、今使用して:

output.GroupBy(x => new { c1 = x.Split(';')[0], c2 = x.Split(';')[1], c3 = x.Split(';')[2] }).Select(//have no idea what should go here); 

答えて

2

まずあなたが匿名型で結果を投影する必要がある列を取得しようあなたが前のクエリで定義する匿名オブジェクト:

var result= query.GroupBy(e=>new {e.c1, e.c2, e.c3}) 
       .Select(g=> new {SurName=g.Key.c1, 
            Name=g.Key.c2, 
            Address=g.Key.c3, 
            Groups=String.Join(",",g.Select(e=>e.c4)}); 

私はいくつかの列を欠けている知っているが、私はあなたのアイデアを得ることができると思います。

PS:2つのクエリで論理を分離しているという事実は、読みやすさのためだけです。どちらのクエリでもどちらでも構いませんが、LINQはdeferred evaluationを使用するため、パフォーマンスを変更することはできません。

0

これは私がそれを行うだろうかです:

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<string> input = new List<string> { 
      "Surname1, Name1;Address1;State1;YES;Group1", 
      "Surname2, Name2;Address2;State2;YES;Group2", 
      "Surname2, Name2;Address2;State2;YES;Group1", 
      "Surname3, Name3;Address3;State3;NO;Group1", 
      "Surname1, Name1;Address2;State1;YES;Group1", 
    }; 
     var transformed = input.Select(s => s.Split(';')) 
      .GroupBy( s => new string[] { s[0], s[1], s[2], s[3] }, 
         (key, elements) => string.Join(";", key) + ";" + string.Join(" ", elements.Select(e => e.Last())), 
      new MyEqualityComparer()) 
      .ToList(); 

    } 
} 

internal class MyEqualityComparer : IEqualityComparer<string[]> 
{ 
    public bool Equals(string[] x, string[] y) 
    { 
     return x[0] == y[0] && x[1] == y[1] && x[2] == y[2]; 
    } 

    public int GetHashCode(string[] obj) 
    { 
     int hashCode = obj[0].GetHashCode(); 
     hashCode = hashCode^obj[1].GetHashCode(); 
     hashCode = hashCode^obj[2].GetHashCode(); 
     return hashCode; 
    } 
} 

は、グループ化キーとして最初の4列を考えてみましょうが、唯一の比較(したがってカスタムIEqualityComparer)のための最初の3を使用します。 次に、(キー、要素)グループがある場合は、キーの要素を結合するように変換します。 (キーは最初の4つの列から構成されています)、グループの各メンバーの最後の要素をスペースで結合して追加します。

関連する問題