2011-01-04 5 views
13

IEnumerableに同じプロパティ値を持つ2つ以上の項目があるかどうかをチェックする方法はありますか?重複するプロパティを持つ項目のIEnumerable <T>を確認してください。

例えばクラス

public class Item 
{ 
    public int Prop1 {get;set;} 
    public string Prop2 {get;set;} 
} 

、その後、私はPROP1で重複する値を持つ項目がある場合はfalseを返す必要があるタイプIEnumerable<Item>

のコレクション。

答えて

15

このメソッドはうまくいくと思います。

public static bool ContainsDuplicates<T>(this IEnumerable<T> source, Func<T, T1> selector) 
{ 
    var d = new HashSet<T1>(); 
    foreach(var t in source) 
    { 
     if(!d.Add(selector(t))) 
     { 
      return true; 
     } 
    } 
    return false; 
} 
+2

またはif(!d.Add(selector(t))){return false; } 'を返します。 – user7116

+0

良い呼び出し、それは少し速いです。 –

+0

これは完璧です!ほんの少し小さいと思います。コレクションに重複が含まれている場合はtrueを返し、重複がない場合はfalseを返します.-) – user137348

4
+4

これは、重複する値があるかどうかを教えてくれません。単に比較者に基づいて異なる値を返すだけです。 – user7116

+2

両方の結果に 'Count()'を使って、何かが削除されたかどうかを確認してください。 – Mehrdad

+1

いくつかのポスターは気付いているかもしれませんし、そうでない人もいるかもしれません(そしてその質問から判断すると、OPはそれらの1つではないかもしれません)。 – user7116

2

IEnumerableから個別の値を選択してから、完全なコレクションの個数をチェックすることができます。

例:

var distinctItemCount = myEnumerable.Select(m => m.Prop1).Distinct().Count(); 

if(distinctItemCount < myEnumerable.Count()) 
{ 
return false; 
} 
+1

動作しません。 「Distinct」は等価性をチェックし、OPが比較しているオブジェクトは必ずしも等しいとは限りません。 –

+0

さて、あなたは 'm => m'から' m => m.Prop1'になります。 – PostMan

+0

コメントありがとう! –

14

あなただけPROP1権をチェックしたいですか?

何について:

IEnumerable<Item> items = ... 
var noDistinct = items.GroupBy(x => x.Prop1).All(x => x.Count() == 1); 
// it returns true if all items have different Prop1, false otherwise 
+1

を使用すると、変数名として' notDistinct'を使用し、Countが大きい場合には 'Any'演算子を使用します。 'Any'を使用することにより、あなたは全体の可算上itterateとshirbr510 @' Any'句 – shirbr510

+0

に一致する最初のケースでは、ループを終了するには、自分自身を強制されていません:うん、正しい – digEmAll

2

これは潜在的にパフォーマンスのために作ることができるが、それは今のところ唯一の正しい答えです。

// Create an enumeration of the distinct values of Prop1 
var propertyCollection = objectCollection.Select(o => o.Prop1).Distinct(); 

// If the property collection has the same number of entries as the object 
// collection, then all properties are distinct. Otherwise there are some 
// duplicates. 
return propertyCollection.Count() == objectCollection.Count(); 
+1

は、皮肉にもそれが正しい答えではありません。ヒント:Prop1はProp2ではなく別個のものである必要があります。 – cdiggins

+0

@cdiggins、LOL。一定。 –

14

短い、一列挙唯一の解決策は、次のようになりますように読み取ることができる

public static bool ContainsDuplicates<T>(this IEnumerable<T> list) 
    => !list.All(new HashSet<T>().Add); 

All商品Addできる場合、リストはない重複を持たない- セットに追加されました。

これは概念的にはJake Pearsonsのソリューションに似ています。しかし、それは投影の独立した概念を放棄する。私たちは、ArrayList.Distinct()を使用して重複したエントリを削除することができ

items.Select(o => o.Prop1).ContainsDuplicates() 
+0

最後の編集でフォーマットがうまくいかず、コードブロックがプレーンテキストとしてフォーマットされているようです。そして、もっとimportantyは、このコードが無効作り、削除する '' - タグを引き起こしました。 私はそれを自分で編集しますが、それは空白のみである、と私は追加する他には何も持っていないので、私がする...固定 – mflodin

+0

おかげで、許可されていませんよ! (奇妙な間違い...何が起こったのだろうか、それは何らかの形の自動タブ変換のように見える) –

+0

@EamonNerbonne n1、また: 'Func 、bool> containsDuplicates = list =>!list.All(new HashSet ().Add); ' –

-1

:としてOPの質問は、解決されるだろう。

例:

私は5つの重複したエントリを持つtesttablecreatedby列を持っています。私は、上記の表考慮

ID Createdby 
=== ======== 
    1 Reddy 
    2 Reddy 
    3 Reddy 
    4 Reddy 

に一つだけの行を取得する必要があり、私は唯一の「レディ」を選択する必要が

DataTable table=new DataTable("MyTable");//Actually I am getting this table data from database 

DataColumn col=new DataColumn("Createdby"); 

var childrows = table.AsEnumerable().Select(row => row.Field<object>(col)).Distinct().ToArray(); 
3
bool x = list.Distinct().SequenceEqual(list); 

xlistが重複している場合trueです。

+1

気の利いたと読めるソリューションが、私は間違っていないよ場合、それはlist''の複数の列挙が発生します – shirbr510

0
public static class EnumerableEx 
{ 
    public static IEnumerable<T> GetDuplicates<T>(this IEnumerable<T> source) 
    { 
     return source.GroupBy(t => t).Where(x => x.Count() > 1).Select(x => x.Key); 
    } 
} 

私は個人的に、私は拡張メソッドのきれいさが好きです。 オブジェクトに平等を判断するためのセレクタが必要ない場合、これはうまく機能します。

関連する問題