web-dev-qa-db-ja.com

アイテムのプロパティを比較して、コレクションにまだアイテムが含まれていない場合、コレクションにアイテムを追加しますか?

基本的に、アイテムのプロパティが既にコレクションにあるかどうかを比較することを除いて、CurrentCollection.Contains(...)に似たことができるようにするにはどうすればよいですか?

public class Foo
{
    public Int32 bar;
}


ICollection<Foo> CurrentCollection;
ICollection<Foo> DownloadedItems;

//LINQ: Add any downloaded items where the bar Foo.bar is not already in the collection?
38
michael

コレクションにまだない要素を見つけることから始めます。

var newItems = DownloadedItems.Where(x => !CurrentCollection.Any(y => x.bar == y.bar));

そして追加するだけです:

foreach(var item in newItems)
{
    CurrentCollection.Add(item);
}

DownloadedItemsのサイズがCurrentCollectionのサイズに近い場合、最初の操作は2次の複雑さになる可能性があることに注意してください。問題が発生する場合(最初に測定してください!)、 HashSet を使用して、複雑さを線形に下げることができます。

// collect all existing values of the property bar
var existingValues = new HashSet<Foo>(from x in CurrentCollection select x.bar);
// pick items that have a property bar that doesn't exist yet
var newItems = DownloadedItems.Where(x => !existingValues.Contains(x.bar));
// Add them
foreach(var item in newItems)
{
    CurrentCollection.Add(item);
}
51

R.Martinho Fernandesメソッドを使用して、1行に変換します。

CurrentCollection.AddRange(DownloadedItems.Where(x => !CurrentCollection.Any(y => y.bar== x.bar)));
12
JumpingJezza

Enumerable.Except を使用できます。

2つのリストを比較し、最初のリストにのみ表示される要素を返します。

CurrentCollection.AddRange(DownloadedItems.Except(CurrentCollection));
9
Yanga

Anyメソッドを呼び出して、コレクション内のオブジェクトのタイプのプロパティと比較する値を渡すことができます

if (!CurrentCollection.Any(f => f.bar == someValue))
{
    // add item
}

より完全なソリューションは次のとおりです。

DownloadedItems.Where(d => !CurrentCollection.Any(c => c.bar == d.bar)).ToList()
    .ForEach(f => CurrentCollection.Add(f));
4
hunter

またはAllを使用して

CurrentCollection
    .AddRange(DownloadedItems.Where(x => CurrentCollection.All(y => y.bar != x.bar)));
2
Janis S.

あなたができることの1つは、リストの代わりにHashSetを解除することが最も簡単な方法だと思います。デフォルトでは、HashSetは冗長な値を追加しません。

1
Khalil Liraqui
var newItems = DownloadedItems.Where(i => !CurrentCollection.Any(c => c.Attr == i.Attr));
0
Bala R

次のようにできます:

CurrentCollection.Any(x => x.bar == yourGivenValue)
0
ub1k