1

タイプ A のオブジェクトの 1 つのコレクションから Guid を抽出して、タイプ B のオブジェクトの別のコレクションからこれらの Guid を除外するために、LINQ をどのように実装しますか。オブジェクト A とオブジェクト B の両方に、「ID」と呼ばれる Guid フィールドがあります。

私は次のものを持っています:

  1. ObservableCollection<Component> component コンポーネントには次IDのタイプのフィールドがありますGuid
  2. ObservableCollection<ComponentInformation> ComponentInformationCollectionComponentInformation には次IDのタイプのフィールドがありますGuid

私の実装:

component =>
{
    if (component != null)
    {
        var cancelledComponents = new List<ComponentInformation>();
        foreach (Component comp in component)
        {
            cancelledComponents.Add(new ComponentInformation() { ID = comp.ID });
        }
        this.ComponentInformationCollection.Remove(cancelledComponents);
    }
});

私が解決しようとしてきたより洗練された解決策があると思いますが、私が遭遇し続ける問題は、タイプがエラーを出さないように「新しいComponentInformation」を作成することです。

====== 最終的な解決策 =======

var cancelledComponentIDs = new HashSet<Guid>(component.Select(x => x.ID));
this.ComponentInformationCollection.Remove(
     this.ComponentInformationCollection.Where(x => cancelledComponentIDs.Contains(x.ID)).ToList());

ありがとう: Jason - これを最終的な解決策のテンプレートとして使用しました (以下にリスト)。Servy - 比較子を使用することもできましたが、この特定のシナリオでは、1 回限りの使用タイプの状況のた​​め、比較子は必要ではなかったと思います。

ComponentInformationCollection は、変更されたときに INotifyChangedEvent (MVVM パターン) をトリガーする Silverlight DependencyProperty であるため、上記のソリューションが私の状況に最適でした。

4

5 に答える 5

4

私はこれを行います:

var ids = new HashSet<Guid>(
              component.Select(x => x.ID)
          );
var keepers = ComponentInformationCollection.Where(x => !ids.Contains(x.ID));
于 2012-04-06T01:10:44.703 に答える
1

LINQ を使用すると、必要な GUID を見つけることができますが、LINQ シーケンスは一般に不変です。コレクションを実際に変更するには、何らかのループを使用する必要があります。秘訣は、削除したい元のコレクションの正しいインスタンスを取得することです。

等価/比較インターフェースの 1 つを実装することは 1 つの方法であり、複数の場所でオブジェクトの等価性を比較する必要がある場合は、間違いなくその方法です。それをしたくない場合は、これで必要なものが得られます。

var removeme = (from x in this.ComponentInformationCollection
               join y in component on x.ID equals y.ID
               select x).ToList();
removeme.ForEach(x => this.ComponentInformationCollection.Remove(x));
于 2012-04-06T01:46:47.100 に答える
1

ID を使用して比較を行う Equals と GetHashCode をまだ定義していない場合Componentは、次のような比較子を定義できます。

class ComponentComparer : IEqualityComparer<Component>
{
  public int Compare(Component a, Component b)
  {
    return a.ID.CompareTo(b.ID);
  }

  public int GetHashCode(Component a)
  {
    return a.ID.GetHashCode();
  }
}

次に、次を使用できます。

var result = componentCollectionA.Except(componentCollectionB, new ComponentComparer());

(私の頭のてっぺんから書かれたものです。コンパイルするには、わずかな変更が必要になる場合があります。)

于 2012-04-06T01:39:32.930 に答える
0

これを解決するには多くの方法があります...これは、コレクションから探しているものを照会する非常に単純な Linq ステートメントです。

var keep = typeAList.Where(a => typeBList.FirstOrDefault(b => a.ID == b.ID) == null);

これは、デモ用にまとめた小さなテストアプリです。

class Program
    {
        static void Main(string[] args)
        {
            List<TypeA> typeAList = new List<TypeA>();
            typeAList.Add(new TypeA() { ID = Guid.NewGuid() });
            typeAList.Add(new TypeA() { ID = Guid.NewGuid() });
            typeAList.Add(new TypeA() { ID = Guid.NewGuid() });

            List<TypeB> typeBList = new List<TypeB>();
            typeBList.Add(new TypeB() { ID = typeAList[0].ID });
            typeBList.Add(new TypeB() { ID = typeAList[1].ID });

            //this is the statement
           var keep = typeAList.Where(a => typeBList.FirstOrDefault(b => a.ID == b.ID) == null);
        }
    }

    class TypeA
    {
        public Guid ID { get; set; }
    }

    class TypeB
    {
        public Guid ID { get; set; }
    }
于 2012-04-06T01:46:02.067 に答える
0

大声で考えます(つまり、プロジェクトを作成してタイプし、これをコンパイルしませんでした)が、どうですか:

var cancelledComponents = component.Select(c=> new ComponentInformation() {ID = c.ID}).ToList();
cancelledComponents.ForEach(c => ComponentInformationCollection.Remove(c));
于 2012-04-06T01:27:06.383 に答える