2013-10-04 6 views
16

Ich habe 2 Listen von verschiedenen Objekten (foo & bar), die die gleiche Eigenschaft teilen können nennen es id.Artikel aus der Liste, die auf Eigenschaft schneiden mit Linq

public List<foo> foo { get; set; } 
public List<bar> bar { get; set; } 

ich alle Objekte aus foo entfernen möchten, die eine ID haben, die in bar

nicht existiert Wie dies in Linq kann getan werden? Ich habe Intersect, RemoveAll & Join betrachtet, kann aber kein Beispiel finden, wo die Listen von einem anderen Typ sind.

Antwort

23

Try this:

foo.RemoveAll(x=> !bar.Any(y=>y.Id==x.Id)); 

!bar.Any(y=>y.Id==x.Id) erhalten, wenn das Element in bar Sammlung ist und wenn es nicht es wird es aus foo Sammlung zu entfernen.

bessere Lösung unter Verwendung von Hashset O (n):

var idsNotToBeRemoved = new HashSet<int>(bar.Select(item => item.Id));                      
foo.RemoveAll(item => !idsNotToBeRemoved.Contains(item.Id)); 

Quelle der zweiten Antwort: https://stackoverflow.com/a/4037674/1714342

EDIT:

@Carra als sagte erste Lösung ist gut für kleine und zweiten Listen ist effizienter für große Listen.

+1

Brilliant @ Wudzik – ojhawkins

+2

Für kleine Listen wird die erste tun. Wenn Sie große Listen verwenden (> 100 oder so), verwenden Sie besser die zweite Lösung. – Carra

7
var foo = foo.Where(f => !bar.Any(b => b.Id == f.Id)).ToList(); 

Denken Sie daran, dass dies eine O (n²) Lösung ist, wird es nicht sehr gut für große Listen arbeiten.

+0

Was wäre eine effizientere Lösung dafür? @Carra – ojhawkins

+0

@ojhawkins Eine Lösung wäre, die Liste von 'id' aus 'bar' in ein hashset (O (n)) zu sammeln und dann jedes Element in' foo' mit demjenigen (O (n)) zu vergleichen als gehe ich die 'bar' Liste für jedes Element in' foo' durch. –

+0

ja ich habe Jon Skeets Beispiel hier gesehen aber konnte es nicht auf mein Beispiel anwenden http://StackOverflow.com/questions/853526/using-linq-to-remove -objects-in-a-list – ojhawkins

Verwandte Themen