CustomsObjectsで満たされた2つの汎用リストがあります。
3つのリストで、これら2つのリスト(最初のリストにあり、2番目のリストにあるアイテムがないアイテム)の違いを取得する必要があります。
使うの.Except()はいい考えだと思っていましたが、使い方がわかりません。
CustomsObjectsで満たされた2つの汎用リストがあります。
3つのリストで、これら2つのリスト(最初のリストにあり、2番目のリストにあるアイテムがないアイテム)の違いを取得する必要があります。
使うの.Except()はいい考えだと思っていましたが、使い方がわかりません。
回答:
使用するのExceptは、まさに正しい方法です。タイプがEqualsandをオーバーライドする場合GetHashCode、または参照タイプの等価性のみに関心がある場合(つまり、2つの参照がまったく同じオブジェクトを参照している場合は、「等しい」のみ)、次のように使用できます。
var list3 = list1.Except(list2).ToList();
たとえばIDによって等号のカスタムアイデアを表現する必要がある場合は、を実装する必要がありますIEqualityComparer<T>。例えば:
public class IdComparer : IEqualityComparer<CustomObject>
{
public int GetHashCode(CustomObject co)
{
if (co == null)
{
return 0;
}
return co.Id.GetHashCode();
}
public bool Equals(CustomObject x1, CustomObject x2)
{
if (object.ReferenceEquals(x1, x2))
{
return true;
}
if (object.ReferenceEquals(x1, null) ||
object.ReferenceEquals(x2, null))
{
return false;
}
return x1.Id == x2.Id;
}
}
次に使用します:
var list3 = list1.Except(list2, new IdComparer()).ToList();
これにより、重複する要素が削除されることに注意してください。複製を保持する必要がある場合は、おそらくlist2次のようなものからセットを作成して使用するのが最も簡単です。
var list3 = list1.Where(x => !set2.Contains(x)).ToList();
あなたはこのようなことをすることができます:
var result = customlist.Where(p => !otherlist.Any(l => p.someproperty == l.someproperty));
Any、Allこれは、2番目のリストに最初のリストのアイテムが含まれる可能性があるためp.someproperty != l.somepropertyです。ただし、最初のリストがチェックされていない場合は、すぐにtrueになります。これにより、両方のリストに存在するアイテムが返されます。これに賛成した6人の恥。
私は強調することが重要だと思います-Exceptメソッドを使用すると、最初のアイテムのみが返され、2番目のアイテムのみが返されます。最初に表示されない2番目の要素は返しません。
var list1 = new List<int> { 1, 2, 3, 4, 5};
var list2 = new List<int> { 3, 4, 5, 6, 7 };
var list3 = list1.Except(list2).ToList(); //list3 contains only 1, 2
しかし、あなたが2つのリストの真の違いを取得したい場合:
最初のアイテムに2番目のアイテムがないアイテムと2番目のアイテムに最初のアイテムがないアイテム。
Exceptを2回使用する必要があります。
var list1 = new List<int> { 1, 2, 3, 4, 5};
var list2 = new List<int> { 3, 4, 5, 6, 7 };
var list3 = list1.Except(list2); //list3 contains only 1, 2
var list4 = list2.Except(list1); //list4 contains only 6, 7
var resultList = list3.Concat(list4).ToList(); //resultList contains 1, 2, 6, 7
または、HashSetのSymmetricExceptWithメソッドを使用できます。しかし、それは呼び出されたセットを変更します:
var list1 = new List<int> { 1, 2, 3, 4, 5};
var list2 = new List<int> { 3, 4, 5, 6, 7 };
var list1Set = list1.ToHashSet(); //.net framework 4.7.2 and .net core 2.0 and above otherwise new HashSet(list1)
list1Set.SymmetricExceptWith(list2);
var resultList = list1Set.ToList(); //resultList contains 1, 2, 6, 7
var third = first.Except(second);
(ToList()後で呼び出すこともできますExcept()遅延コレクションを参照したくない場合は、のにます。)
Except()値が比較される場合、メソッドは、既定の比較を使用して値を比較するような塩基のデータ・タイプのものであるint、string、decimal等
そうでない場合、比較はオブジェクトアドレスによって行われますが、これはおそらく必要なことではありません...その場合は、カスタムオブジェクトを実装しますIComparable(またはカスタムIEqualityComparerを実装してExcept()メソッドに渡します)。
Except拡張メソッドは2つのIEumerableで動作するため、O(n ^ 2)操作になるように思えます。パフォーマンスに問題がある場合(リストが大きい場合)、list1からHashSetを作成し、HashSetのExceptWithメソッドを使用することをお勧めします。
Enumerable.Except内部で使用するHashSetか、または類似したもの。それは間違いなくナイーブO(n ^ 2)アルゴリズムを使用しません。
これが私の解決策です:
List<String> list1 = new List<String>();
List<String> list2 = new List<String>();
List<String> exceptValue = new List<String>();
foreach(String L1 in List1)
{
if(!List2.Contains(L1)
{
exceptValue.Add(L1);
}
}
foreach(String L2 in List2)
{
if(!List1.Contains(L2)
{
exceptValue.Add(L2);
}
}
少し遅れましたが、ここで私のための実用的な解決策があります
var myBaseProperty = (typeof(BaseClass)).GetProperties();//get base code properties
var allProperty = entity.GetProperties()[0].DeclaringType.GetProperties();//get derived class property plus base code as it is derived from it
var declaredClassProperties = allProperty.Where(x => !myBaseProperty.Any(l => l.Name == x.Name)).ToList();//get the difference
上記のコードで、基本クラスと派生クラスのリストのプロパティの違いを取得しています
List<ObjectC> _list_DF_BW_ANB = new List<ObjectC>();
List<ObjectA> _listA = new List<ObjectA>();
List<ObjectB> _listB = new List<ObjectB>();
foreach (var itemB in _listB )
{
var flat = 0;
foreach(var itemA in _listA )
{
if(itemA.ProductId==itemB.ProductId)
{
flat = 1;
break;
}
}
if (flat == 0)
{
_list_DF_BW_ANB.Add(itemB);
}
}
両方のリストがIEnumerableインターフェイスを実装している場合は、LINQを使用してこれを実現できます。
list3 = list1.where(i => !list2.contains(i));
IEnumerable.Except代わりに使用してください。
Exceptが、これをSetオペレーションとして追加すると、結果のリストには異なる値{'A','A','B','C'}.Except({'B','C'})が返されます(例:戻り値){'A'}