2016-03-25 16 views
4

次の構造のリストが2つあります。 <の各名はリストです。私はそれらの2つのリストを1つのList<Server>にまとめたいと思います。以下の擬似コードは、そのような2つのリストを表示し、どのように結果は次のようになります。C#LINQを使用してネストされたリストを持つ2つのリストを結合する

<Servers>       <Servers> 
+...        +... 
+-- Server A,1      +-- Server A,1 
|  +...      |  +...  
|  +--<Maps>     |  +--<Maps> 
|   +--Map x    |   +--Map x 
|    +...    |    +...  
|    +--<Times>   |    +--<Times> 
|     +--Time i  |     +--Time l 
|     +--Time j  |    +--<Jumps> 
|    +--<Jumps>   |     +--Jump t 
|     +--Jump s  |     +--Jump u 
|   +--Map y    |   +--Map z 
|    +...    |    +... 
|    +--<Times>   |    +--<Jumps> 
|     +-- Time k  |     +--Jump v 
+-- Server B,1      +-- Server B,2 

結果は次のようになります。

<Servers> 
+... 
+-- Server A,1 
| +... 
| +--<Maps> 
|  +-- Map x 
|   +... 
|   +--<Times> 
|    +--Time i 
|    +--Time j 
|    +--Time l 
|   +--<Jumps> 
|    +--Jump s 
|    +--Jump t 
|    +--Jump u 
|  +-- Map y 
|   +... 
|   +--<Times> 
|    +--Time k 
|  +-- Map z 
|   +... 
|   +--<Jumps> 
|    +--Jump v 
+-- Server B,1 
+-- Server B,2 

私は完全外部を使用してみましたLINQと結合したが、結果はどのような私にもありませんでしたなぜなら、私は、同じキーを持っていたサーバーがマッチしていなかったことを理解していなかったからです。だから私はいつも同じデータを持つ同じサーバーの複製を持っていました。それは私がlinqでそれをやろうとするのをやめ、リストを手動でマージするためにループを使用したときです。

以下のコードは私に望ましい結果リストを与えます。今のところ私はもっと良い方法を見つけるまでそれを使用します。 linqでそれをやっている簡単な/簡単な方法はありますか?ラムダ式を使う?

foreach (Server importServer in oImportList) 
     { 
      if (!CoreList.Contains(importServer)) 
      { 
       CoreList.Add(importServer); 
       continue; 
      } 

      Server coreServer = CoreList.FirstOrDefault(o => o.Equals(importServer)); 
      coreServer.Name = importServer.Name; 
      coreServer.KZTimerVersion = importServer.KZTimerVersion; 
      foreach(Map importMap in importServer.Maps) 
      { 
       if (!coreServer.Maps.Contains(importMap)) 
       { 
        coreServer.Maps.Add(importMap); 
        continue; 
       } 
       Map coreMap = coreServer.Maps.FirstOrDefault(o => o.Equals(importMap)); 
       coreMap.Jumps.Concat(importMap.Jumps); 
       coreMap.Times.Concat(importMap.Times); 
      } 
     } 
+0

あなたは正しい考えを持っていると思います。ネストされた 'Join'sが間違ったパラメータを渡したようです。例えば、 'Maps'ジョインでは、' coreServer.Maps'と 'oImportList'に参加しようとしています...これは' coreServer.Maps'と 'importServer.Maps'であると思われます。 – 31eee384

+0

私はあなたの助けを借りてコードを手に入れることができましたが、結果は私が望むリストではないことがわかりました。それは両方のリストに存在する要素だけを含んでいました。 – schm0ftie

+0

ああ、申し訳ありません...私は非常にまれに '結合'を使用したので、私は混乱してしまいました。私はあなたのために働くかもしれない 'GroupBy'と' Select'を使って答えを元に戻しました。前に削除したのは、私が間違っていると思ったからです。 – 31eee384

答えて

0

あなたは.Unionを探しているかもしれませんが、私はそれはあなたが本当に必要なものだとは思わないので、それは、ネストされたリストを扱っていません。私は完全な例を設定 - 構造は、私はあなたが簡単にコアLINQを適用することができると思いますあなたと同じではないが:

using System; 
using System.Collections.Generic; 
using System.Linq; 

public class Map 
{ 
    public string Name { get; set; } 
    public IEnumerable<MapProperty> Properties { get; set; } 
} 

public class MapProperty 
{ 
    public string Name { get; set; } 
} 

public class Test 
{ 
    public static IEnumerable<Map> Merge(IEnumerable<Map> a, IEnumerable<Map> b) 
    { 
     return a.Concat(b) 
      .GroupBy(map => map.Name) 
      .Select(mg => new Map 
      { 
       Name = mg.Key, 
       Properties = mg.SelectMany(v => v.Properties) 
        .GroupBy(p => p.Name) 
        .Select(pg => new MapProperty { Name = pg.Key }) 
      }); 
    } 

    public static void Main() 
    { 
     var mapsA = new[] 
     { 
      new Map 
      { 
       Name = "MapA", 
       Properties = new[] 
       { 
        new MapProperty { Name = "Jumps" }, 
        new MapProperty { Name = "Hops" }, 
       } 
      }, 
      new Map 
      { 
       Name = "MapB", 
       Properties = new[] 
       { 
        new MapProperty { Name = "Jumps" }, 
        new MapProperty { Name = "Skips" }, 
       } 
      } 
     }; 
     var mapsB = new[] 
     { 
      new Map 
      { 
       Name = "MapA", 
       Properties = new[] 
       { 
        new MapProperty { Name = "Jumps" }, 
        new MapProperty { Name = "Times" }, 
       } 
      }, 
      new Map 
      { 
       Name = "MapC", 
       Properties = new[] 
       { 
        new MapProperty { Name = "Jumps" }, 
        new MapProperty { Name = "Skips" }, 
       } 
      } 
     }; 

     var mapsC = Merge(mapsA, mapsB); 

     foreach (var map in mapsC) 
     { 
      Console.WriteLine($"{map.Name}"); 
      foreach (var prop in map.Properties) 
      { 
       Console.WriteLine($"\t{prop.Name}"); 
      } 
     } 
    } 
} 

出力:

MapA 
    Jumps 
    Hops 
    Times 
MapB 
    Jumps 
    Skips 
MapC 
    Jumps 

Mergeは重要なビットです。最初にabを1つのリストに入れて、GroupByという名前は同じ名前のマップのグループを形成します。 Selectはそれぞれのグループを取り、そのグループ内のすべてMapsの内容で新しいMapを作成します(これはマージです)。それから、私は新しいマージされた地図の内容に同じことをして、MapPropertyをグループ化し、それらを結合/マージします。

具体的なケースでは、すべてをマージするための作業とレベルが少し必要です。私はツリー内の各レベルのMergeメソッドを作成し、各親レベルから次のレベルを呼び出す方法を見つけることをお勧めします。大量の linqチェーンで終わることはありません。

関連する問題