LINQ: Wählen Sie aus, wo das Objekt keine Elemente aus der Liste enthält


77

Ich habe hier Probleme mit der LINQ-Syntax ... dachte, ich würde sie hier rauswerfen. Ich kann nirgendwo anders genau das finden, wonach ich suche.

OK, sag ich habe das:

public class Bar
{
   public int BarId { get; set; }
}

public class Foo
{
   public List<Bar> BarList { get; set; }
}

List<Foo> fooBunch = GetABunchOfFoos(); //let's just assume I'm getting more than one
List<Foo> fooSelect = new List<Foo>;
List<Bar> filterBars = GetAFewBars(); //assume I'm getting like 2 or 3

fooSelect = (from f in fooBunch
             where !(from b in f.BarList select b.BarId).Contains(ITEM FROM filterBars.BarId)
             select f).ToList();

Kurz gesagt, ich möchte LINQ verwenden, um meine Liste von Objekten basierend auf Objekten aus einer anderen Liste herauszufiltern. Ich hoffe das macht Sinn. Ich glaube, ich bin nur im Contains-Teil verloren ... Ich weiß nicht, wie ich das schreiben soll.

Antworten:


126

Im Allgemeinen suchen Sie nach der Erweiterung "Außer".

var rejectStatus = GenerateRejectStatuses();
var fullList = GenerateFullList();
var rejectList = fullList.Where(i => rejectStatus.Contains(i.Status));
var filteredList = fullList.Except(rejectList);

In diesem Beispiel sollte GenerateRegectStatuses () die Liste der Status sein, die Sie ablehnen möchten (oder konkreter ausgedrückt anhand Ihres Beispiels eine List<int>der IDs).


Das ist wirklich nah ... der Trick wäre, die RejectList aus dynamischen Status zu erstellen. Es wäre eher so, als ob i => i.Status in (Liste <Status>). Kann ich so etwas machen? Grundsätzlich eine andere LINQ-Anweisung, denke ich?
Farina

1
Um die Ablehnungsliste zu erstellen, müssten Sie nur einen Weg finden, um eine Liste der Ablehnungen zu erhalten, die Sie nicht möchten. Zum Beispiel: var rejectList = fullList.Where(i => rejectStatuses.Contains(i.Status)); Ich werde meine ursprüngliche Antwort aktualisieren, um diese Änderung widerzuspiegeln.
Thebigcheeze

2
Wie würde ich das in nur einer Zeile machen? Ich verstehe, dass es möglicherweise nicht möglich ist.
JustJohn

78

Speichern Sie dies in einer spezifischeren Sammlung nur der IDs, die Sie nicht möchten

var notTheseBarIds = filterBars.Select(fb => fb.BarId);

dann versuchen Sie dies:

fooSelect = (from f in fooBunch
             where !notTheseBarIds.Contains(f.BarId)
             select f).ToList();

oder dieses:

fooSelect = fooBunch.Where(f => !notTheseBarIds.Contains(f.BarId)).ToList();

Nett. Ich mag diese Antwort besser. +1
JoshYates1980

Diese Antwort ist besser als die ausgewählten
Rarepuppers

Sauber und einfach! Schön
Cata Hotea

@ Rarepuppers - Ich verbringe ein paar Minuten damit, die akzeptierte Antwort zu verstehen, und habe dann hier nachgeschlagen, was ich bereits eingegeben habe, bevor ich sicher war, ob es so funktioniert ...
Jleach

Dies sollte die akzeptierte Antwort sein. Ich habe versucht zu verstehen, wie es funktioniert. Danke vielmals!
Xonshiz

5

Ich habe dies nicht versucht, daher garantiere ich jedoch nichts

foreach Bar f in filterBars
{
     search(f)
}
Foo search(Bar b)
{
    fooSelect = (from f in fooBunch
                 where !(from b in f.BarList select b.BarId).Contains(b.ID)
                 select f).ToList();

    return fooSelect;
}

2
Nach allem, was ich sagen kann, wird b.ID nicht kompiliert. Die Contains-Methode scheint den Kontext von b zu verlieren.
Farina

2
Sie verwenden zwei Variablen mit dem Namen b, und der Compiler findet sie wahrscheinlich nicht eindeutig.
Justin Morgan

4

Probieren Sie diesen einfachen LINQ aus:

//For a file list/array
var files = Directory.GetFiles(folderPath, "*.*", SearchOption.AllDirectories);

//simply use Where ! x.Contains
var notContain = files.Where(x => ! x.Contains(@"\$RECYCLE.BIN\")).ToList();

//Or use Except()
var containing = files.Where(x => x.Contains(@"\$RECYCLE.BIN\")).ToList();
    notContain = files.Except(containing).ToList();
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.