2

dataBにあり、プロパティcの値が異なるdataAのアイテムのサブセットを取得しようとしています。プロパティaとbはインデックスとして使用できるので、有用なペアのみを除外して、それらが異なるc値を持っているかどうかを確認しようとしました。

これは私が思いついたlinq式であり、機能しますが、このサブセットを見つけるためのより良い/より速い方法が必要なようです。

var itemsInBoth = from item in dataA
                  from item2 in dataB
                  where item.a == item2.a && item.b == item2.b
                      select new
                      {
                          first= item,
                          second = item2
                      };
var haveDifferentC = from item in itemsInBoth 
                     where item.first.c != item.second.c
                     select item.first;
4

2 に答える 2

3

David B から提供された回答に基づいて、私は最終的に彼の方法を少し修正したバージョンに落ち着きました。違いはわずかですが、主に (私のような) 表現力豊かな構文を好む人向けのバージョンを示すために、これを共有すると思いました。

また、グループ化する代わりに、匿名のキーと値のペアを使用して構造を簡素化することにしました。

var dictA = (from item in dataA
             select new
             {
                 key = CreateIndexValue(item.a, item.b),
                 value = item
             }).ToDictionary(kv => kv.key, kv => kv.value);
var dictB = (from item in dataB
             select new
             {
                 key = CreateIndexValue(item.a, item.b),
                 value = item
             }).ToDictionary(kv => kv.key, kv => kv.value);
var filesInBoth = from item in dictA
                  where dictB.ContainsKey(item.Key)
                  select new
                  {
                      itemA = dictA[item.Key],
                      itemB = dictB[item.Key]
                  };
var differentSize = from item in filesInBoth
                    where item.itemA.c!= item.itemB.c
                    select item.itemA;
于 2009-03-03T17:50:53.230 に答える
2

もっと早く?あなたが持っているのは O(n^2) です。最初のリストの各項目は、2 番目のリストの項目を完全に反復します。その結合で冗長な繰り返しを削除する必要があります。これを行う 1 つの方法は、別の構造を使用して O(1) ルックアップを実行することです。

テストされていない(チェックされていない)コードは次のとおりです。

var dictionaryA = dataA
  .GroupBy(item => new {a = item.a, b = item.b})
  .ToDictionary(g => g.Key, g => g.ToList());

var dictionaryB = dataB
  .GroupBy(item => new {a = item.a, b = item.b})
  .ToDictionary(g => g.Key, g => g.ToList());

var results = dictionaryA
  .Where(g1 => dictionaryB.ContainsKey(g1.Key))
  .Select(g1 => new {g1 = g1, g2 = dictionaryB[g1.Key]})
  .SelectMany(pair =>
    pair.g1.SelectMany(item1 =>
      pair.g2
      .Where(item2 => item2.c != item1.c)
      .Select(item2 => new {item1, item2})
    )
  );

a,b ペアが各リストで一意である場合の簡略版を次に示します。

var dictionaryA = dataA
  .ToDictionary(item => new {a = item.a, b = item.b}, item => item);

var dictionaryB = dataB
  .ToDictionary(item => new {a = item.a, b = item.b}, item => item);

var results = dictionaryA
  .Where(e1 => dictionaryB.ContainsKey(e1.Key))
  .Select(e1 => new {i1 = e1.Value, i2 = dictionaryB[e1.Key]})
  .Where(pair => pair.i1.c != pair.i2.c);
于 2009-03-03T15:00:32.157 に答える