24

私はクラスを持っています:

class ThisClass
{
  private string a {get; set;}
  private string b {get; set;}
}

Linq の Intersect メソッドと Except メソッドを使用したいと思います。つまり、次のようになります。

private List<ThisClass> foo = new List<ThisClass>();
private List<ThisClass> bar = new List<ThisClass>();

次に、2 つのリストを別々に入力します。たとえば、次のようにしたいと思います(これが正しくないことはわかっていますが、単なる疑似コードです)。

foo[a].Intersect(bar[a]);

どうすればいいですか?

4

7 に答える 7

39

交差させたい単一のプロパティのリストが必要な場合は、他のすべてのきれいな LINQ ソリューションがうまく機能します。しかし!ただし、クラス全体で交差したい場合、結果としてList<ThisClass>代わりにa がList<string>必要な場合は、独自の等値比較子を作成する必要があります。

foo.Intersect(bar, new YourEqualityComparer());

と同じExcept

public class YourEqualityComparer: IEqualityComparer<ThisClass>
{

    #region IEqualityComparer<ThisClass> Members


    public bool Equals(ThisClass x, ThisClass y)
    {
        //no null check here, you might want to do that, or correct that to compare just one part of your object
        return x.a == y.a && x.b == y.b;
    }


    public int GetHashCode(ThisClass obj)
    {
        unchecked
        {
            var hash = 17;
                            //same here, if you only want to get a hashcode on a, remove the line with b
            hash = hash * 23 + obj.a.GetHashCode();
            hash = hash * 23 + obj.b.GetHashCode();

            return hash;    
        }
    }

    #endregion
}
于 2012-05-17T10:00:27.550 に答える
35

多分

// returns list of intersecting property 'a' values
foo.Select(f => f.a).Intersect(bar.Select(b => b.a));

ところで、プロパティaは公開する必要があります。

于 2012-05-17T09:54:47.177 に答える
5

交差して比較するのと比較して、これの速度はわかりませんが、どうですか:

//Intersect
var inter = foo.Where(f => bar.Any(b => b.a == f.a));
//Except - values of foo not in bar
var except = foo.Where(f => !bar.Any(b => b.a == f.a));
于 2015-01-14T18:05:05.013 に答える
2
foo.Select(x=>x.a).Intersect(bar.Select(x=>x.a))
于 2012-05-17T09:55:25.933 に答える
0

これが古いことは知っていますが、クラス自体で Equals と GetHashCode をオーバーライドすることもできませんか?

class ThisClass
{
  public string a {get; set;}
  private string b {get; set;}

  public override bool Equals(object obj)
  {
    // If you only want to compare on a
    ThisClass that = (ThisClass)obj;
    return string.Equals(a, that.a/* optional: not case sensitive? */);
  }

  public override int GetHashCode()
  {
    return a.GetHashCode();
  }
}
于 2016-11-10T19:44:14.407 に答える
0

望ましい効果とは正確には何ですか?の一意の値によって 2 つのインスタンスが識別されたときにa、クラス内のすべての で構成される文字列のリストを取得しますか?それとも のリストを取得しますか?ThisClassThisClassa

前者の場合、@lazyberezovksy と @Tilak からの 2 つの回答が機能するはずです。後者の場合は、オーバーライドする必要があります。IEqualityComparer<ThisClass>または、2 つの同等のインスタンスを作成するIEquatable<ThisClass>理由Intersectがわかります。ThisClass

 private class ThisClass : IEquatable<ThisClass>
 {
     private string a;

     public bool Equals(ThisClass other)
     {
        return string.Equals(this.a, other.a);
     }
 }

次に、次のように呼び出すことができます。

 var intersection = foo.Intersect(bar);     
于 2012-05-17T10:02:49.410 に答える
-3

IEqualityComparer を作成する必要があります。IEqualityComparer を Intersect() メソッドに渡すことができます。これにより、リスト(バーと交差する)を簡単に取得できます。

var intersectionList = foo.Intersect(bar, new ThisClassEqualityComparer()).ToList();


class ThisClassEqualityComparer : IEqualityComparer<ThisClass>
{

    public bool Equals(ThisClass b1, ThisClass b2)
    {
        return b1.a == b2.a;
    }


    public int GetHashCode(Box bx)
    {
       // To ignore to compare hashcode, please consider this.
       // I would like to force Equals() to be called
       return 0;
    }

}
于 2012-05-17T10:01:30.470 に答える