it-swarm.com.de

Hinzufügen von Elementen zu einer Sammlung, wenn die Sammlung diese NICHT bereits enthält, indem eine Eigenschaft der Elemente verglichen wird?

Wie kann ich es im Grunde so machen, dass ich etwas Ähnliches tun kann: CurrentCollection.Contains(...), außer durch einen Vergleich, ob die Eigenschaft des Elements bereits in der Sammlung enthalten ist?

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?
28
michael

Sie beginnen, indem Sie herausfinden, welche Elemente sich noch nicht in der Sammlung befinden:

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

Und füge sie einfach hinzu:

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

Beachten Sie, dass die erste Operation eine quadratische Komplexität aufweisen kann, wenn die Größe von DownloadedItems der Größe von CurrentCollection nahe kommt. Wenn dies zu Problemen führt (zuerst messen!), Können Sie eine HashSet verwenden, um die Komplexität auf linear zu reduzieren:

// 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);
}
44

R.Martinho-Fernandes-Methode verwenden und in 1 Zeile konvertieren:

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

Sie können Enumerable.Except verwenden: 

Es werden die beiden Listen verglichen und Elemente zurückgegeben, die nur in der ersten Liste erscheinen.

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

Sie können die Any-Methode aufrufen und einen Wert übergeben, der mit der beliebigen Eigenschaft des Objekttyps in der Auflistung verglichen wird

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

eine umfassendere Lösung könnte sein:

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

Oder mit All 

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

Eine Sache, die Sie tun können. Ich denke, es ist der einfachste Weg, ein HashSet anstelle einer Liste zu aktivieren. Standardmäßig fügt das HashSet keine redundanten Werte hinzu. 

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

Du könntest es so machen: 

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