none
Contains mit ListItem RRS feed

  • Frage

  • Hallo,

    ich habe von IDs die ich mit einer anderen Liste vergleichen muss.

     
    var idList = param.Split(',').Select(i => { int retval = 0; int.TryParse(i, out retval); return retval; });
    
    List<ListItem> bewertungen = new List<ListItem>();
    bewertungen.Add(new ListItem("Sehr gut", "5"));
    bewertungen.Add(new ListItem("Gut", "4"));
    bewertungen.Add(new ListItem("Befriedigend", "3"));
    bewertungen.Add(new ListItem("Ungenügend", "2"));
    bewertungen.Add(new ListItem("Schlecht", "1"));

    In einer anderen Liste sollen nur die Werte mit AddRang übergeben werden die in der Liste Bewertungen sind und auch in der List idList enthalten sind.

    _selectedBewertungList.AddRange(bewertungen.Where(a => idList.Contains()) ....
    Hört sich total simpel an aber ich bekomme das trotzdem nicht hin.
    Könnt Ihr mir bitte weiterhelfen?

     

    Freitag, 23. Mai 2014 13:34

Antworten

  • Hallo,
    meinst du so etwas?

    _selectedBewertungList.AddRange(bewertungen.Where(a => idList.Contains(int.Parse(a.Number))));

    Mit Where wird jedes Element heraus gefiltert, für das eine Bedingung zutrifft. Wenn also idList einen Wert enthält, der der Zahl vom ListItem entspricht, wird das Item heraus gefiltert.

    Es wäre aber besser, wenn du auch in ListItem die Zahl als Zahl und nicht als String speicherst. So sparst du dir das ständige Umwandeln und Fehler sind unwahrscheinlicher.


    Tom Lambert - C# MVP
    Bitte bewertet- und markiert Beiträge als Antwort. Danke.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Freitag, 23. Mai 2014 13:46
    Moderator
  • Hi,

    hier nochmal eine Alternative mit LINQ und JOIN, ist vielleicht etwas intuitiver, wenn man schon SQL Background hat.

    Der Code beinhaltet einmal ein Beispiel mit einer Liste und einmal mit einem Dictionary:

        class Program
        {
            static void Main(string[] args)
            {
                TestList();
                TestDictionary();
    
                Console.ReadLine();
            }
    
            private static void TestDictionary()
            {
                Dictionary<int, string> basisBewertungen = new Dictionary<int, string>
                {
                    {1, "Sehr gut"},
                    {2, "Gut"},
                    {3, "Befriedigend"},
                    {4, "Ausreichend"},
                    {5, "Mangelhaft"},
                    {6, "Schlecht"},
                };
    
                List<int> noten = new List<int> { 2, 3, 4 };
    
                var schuelerBewertung = (from keyValue in basisBewertungen
                                         join note in noten
                                         on
                                         keyValue.Key equals note
                                         select new Bewertung { Id = keyValue.Key, Bezeichnung = keyValue.Value }).ToList();
    
                PrintZeugnis("John Doe", schuelerBewertung);
    
            }
    
            private static void TestList()
            {
                List<Bewertung> basisBewertungen = new List<Bewertung>
                {
                    new Bewertung { Bezeichnung = "Sehr gut", Id = 1},
                    new Bewertung { Bezeichnung = "Gut", Id = 2},
                    new Bewertung { Bezeichnung = "Befriedigend", Id = 3},
                    new Bewertung { Bezeichnung = "Ausreichend", Id = 4},
                    new Bewertung { Bezeichnung = "Mangelhaft", Id = 5},
                    new Bewertung { Bezeichnung = "Schlecht", Id = 6}
    
                };
    
                List<int> noten = new List<int> { 2, 3, 4 };
    
                var schuelerBewertung = (from bewertung in basisBewertungen
                                         join note in noten
                                         on
                                         bewertung.Id equals note
                                         select bewertung).ToList();
    
                PrintZeugnis("John Doe", schuelerBewertung);
            }
    
            static void PrintZeugnis(string name, List<Bewertung> bewertungen)
            {
                Console.WriteLine("{0} hat folgende Noten: ", name);
                foreach (Bewertung bewertung in bewertungen)
                {
                    Console.WriteLine("{0}", bewertung.Bezeichnung);
                }
            }
        }
    
    
        public class Bewertung
        {
            public int Id { get; set; }
            public string Bezeichnung { get; set; }
        }

    Gruß

    JohSu

    Donnerstag, 12. Juni 2014 13:46

Alle Antworten

  • Hallo,

    das geht mit Contains(a.id) oder auch Intersect, siehe dazu:

    http://stackoverflow.com/questions/2381049/intersect-linq-query

    Gruß Elmar

    Freitag, 23. Mai 2014 13:44
    Beantworter
  • Hallo,
    meinst du so etwas?

    _selectedBewertungList.AddRange(bewertungen.Where(a => idList.Contains(int.Parse(a.Number))));

    Mit Where wird jedes Element heraus gefiltert, für das eine Bedingung zutrifft. Wenn also idList einen Wert enthält, der der Zahl vom ListItem entspricht, wird das Item heraus gefiltert.

    Es wäre aber besser, wenn du auch in ListItem die Zahl als Zahl und nicht als String speicherst. So sparst du dir das ständige Umwandeln und Fehler sind unwahrscheinlicher.


    Tom Lambert - C# MVP
    Bitte bewertet- und markiert Beiträge als Antwort. Danke.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Freitag, 23. Mai 2014 13:46
    Moderator
  • Hallo,

    vielen Dank für die Antwort.
    Hast du bitte ein kurzes Beispiel wie ich das in eine Zahl speichern kann?

    Mit der vorgeschlagen Lösung bekomme ich eine Fehlermeldung ListItem enthält keine Definition für Number. Ich muss die Felder bestimmt irgendwie erst benennen. aber wie?

    Freitag, 23. Mai 2014 14:40
  • Du übergibst dem Konstruktor von ListItem 2 Werte. Der 2. Ist eine Zahl. Irgend etwas machst du mit der Zahl. Ich bin in meinem Beispiel davon ausgegangen, dass der Wert der Zahl in der Eigenschaft Number gespeichert wird.

    Um aus dem String eine Zahl zu machen, ändere einfach den Typ des 2. Konstruktor Parameters und der Eigenschaft von string auf int. Der LINQ-Ausdruck braucht die Parse-Methode dann nicht mehr aufzurufen:

    _selectedBewertungList.AddRange(bewertungen.Where(a => idList.Contains(a.Number)));


    Tom Lambert - C# MVP
    Bitte bewertet- und markiert Beiträge als Antwort. Danke.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Freitag, 23. Mai 2014 14:47
    Moderator
  • Ich habe jetzt einfach ein Dictionary genommen

              var bewertungenx = new Dictionary<string, int>();
              bewertungenx.Add("Sehr gut", 1);
              bewertungenx.Add("Gut", 4);
              bewertungenx.Add("Befriedigend", 3);
              bewertungenx.Add("Ungenügend", 2);
              bewertungenx.Add("Schlecht", 1);

    a.Number wir aber trotzdem nicht erkannt.

    _selectedBewertungList.AddRange(bewertungenx.Where(a => idList.Contains(a.Number)));

    Fehler	2	"System.Collections.Generic.KeyValuePair<string,int>" enthält keine Definition für "Number", und es konnte keine Erweiterungsmethode "Number" gefunden werden, die ein erstes Argument vom Typ "System.Collections.Generic.KeyValuePair<string,int>" akzeptiert.

    Freitag, 23. Mai 2014 14:57
  • Du hast scheinbar nicht verstanden was hier das Problem ist. Natürlich wird "Number" nicht gefunden, schließlich ist der Wert eines KeyValuePairs durch die Value-Eigenschaft abrufbar.

    Ich hatte die Eigenschaft in meinem Beispiel Number genannt.

    Das sind aber Grundlagen, die Vorraussetzungen sind um LINQ zu verstehen.


    Tom Lambert - C# MVP
    Bitte bewertet- und markiert Beiträge als Antwort. Danke.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Freitag, 23. Mai 2014 15:14
    Moderator
  • Hi,

    hier nochmal eine Alternative mit LINQ und JOIN, ist vielleicht etwas intuitiver, wenn man schon SQL Background hat.

    Der Code beinhaltet einmal ein Beispiel mit einer Liste und einmal mit einem Dictionary:

        class Program
        {
            static void Main(string[] args)
            {
                TestList();
                TestDictionary();
    
                Console.ReadLine();
            }
    
            private static void TestDictionary()
            {
                Dictionary<int, string> basisBewertungen = new Dictionary<int, string>
                {
                    {1, "Sehr gut"},
                    {2, "Gut"},
                    {3, "Befriedigend"},
                    {4, "Ausreichend"},
                    {5, "Mangelhaft"},
                    {6, "Schlecht"},
                };
    
                List<int> noten = new List<int> { 2, 3, 4 };
    
                var schuelerBewertung = (from keyValue in basisBewertungen
                                         join note in noten
                                         on
                                         keyValue.Key equals note
                                         select new Bewertung { Id = keyValue.Key, Bezeichnung = keyValue.Value }).ToList();
    
                PrintZeugnis("John Doe", schuelerBewertung);
    
            }
    
            private static void TestList()
            {
                List<Bewertung> basisBewertungen = new List<Bewertung>
                {
                    new Bewertung { Bezeichnung = "Sehr gut", Id = 1},
                    new Bewertung { Bezeichnung = "Gut", Id = 2},
                    new Bewertung { Bezeichnung = "Befriedigend", Id = 3},
                    new Bewertung { Bezeichnung = "Ausreichend", Id = 4},
                    new Bewertung { Bezeichnung = "Mangelhaft", Id = 5},
                    new Bewertung { Bezeichnung = "Schlecht", Id = 6}
    
                };
    
                List<int> noten = new List<int> { 2, 3, 4 };
    
                var schuelerBewertung = (from bewertung in basisBewertungen
                                         join note in noten
                                         on
                                         bewertung.Id equals note
                                         select bewertung).ToList();
    
                PrintZeugnis("John Doe", schuelerBewertung);
            }
    
            static void PrintZeugnis(string name, List<Bewertung> bewertungen)
            {
                Console.WriteLine("{0} hat folgende Noten: ", name);
                foreach (Bewertung bewertung in bewertungen)
                {
                    Console.WriteLine("{0}", bewertung.Bezeichnung);
                }
            }
        }
    
    
        public class Bewertung
        {
            public int Id { get; set; }
            public string Bezeichnung { get; set; }
        }

    Gruß

    JohSu

    Donnerstag, 12. Juni 2014 13:46
  • Hallo,

    ein Beispiel mit Dictionary:

    var bewertungenx = new Dictionary<string, int>();
    bewertungenx.Add("Sehr gut", 1);
    bewertungenx.Add("Gut", 4);
    bewertungenx.Add("Befriedigend", 3);
    bewertungenx.Add("Ungenügend", 2);
    bewertungenx.Add("Schlecht", 1);
    
    int[] bewArray = new int[bewertungenx.Count];
    bewertungenx.Values.CopyTo(bewArray, 0);
    //Wenn man eine Liste braucht, dann
    List<int> bewList = new List<int>();
    bewList.AddRange(bewArray);

    Viele Grüße,

    Iso

    Donnerstag, 12. Juni 2014 14:14