none
Wie kann ich mit LINQ in der Liste nach der größten Zahl von der Eigenschaft ID suchen? RRS feed

  • Frage

  • Hallo,
    ich will in einer Liste nach der größten Zahl von der Eigenschaft ID suchen.
    Die Liste besteht aus Objekten. Jedes Objekt hat die Eigenschaft ID und eine Eigenschaft SubIDs, welche auch wieder eine Liste mit Objekten ist.
    Ich habe ein sehr vereinfachtes Beispiel erstellt.
    Die Listen mit foreach durchlaufen und sich den maximalen Wert von ID merken funktioniert. Mit LINQ geht es sicherlich einfacher.
    Wie kann ich mit LINQ in der Liste values nach der größten Zahl von der Eigenschaft ID suchen (das Ergebnis soll 12 ergeben)?

    Alexander

    public class Test
    {
        public int ID { get; set; }

        public List<Test> SubIDs { get; set; }

        public Test()
        {
            SubIDs = new List<Test>();
        }
    }

    private void GetMaxValue()
    {
        List<Test> values = new List<Test>();

        var test = new Test {ID = 1};
        test.SubIDs.Add( new Test {ID = 2});
        test.SubIDs.Add(new Test { ID = 12 });
        test.SubIDs.Add(new Test { ID = 4 });
        values.Add(test);

        test = new Test { ID = 7 };
        test.SubIDs.Add(new Test { ID = 5 });
        test.SubIDs.Add(new Test { ID = 6 });
        test.SubIDs.Add(new Test { ID = 3 });
        values.Add(test);

        //int maxID = values        // ???   Ergebnis soll 12 sein
    }

    Freitag, 4. September 2020 15:21

Antworten

  • Hi,

    ich habe mal die Klassen von Thomas genommen und die Abfrage könnte so aussehen:

    var result = values.Concat(values.SelectMany(x => x.SubIDs)).Max(i => i.ID);

    Gruß


    Freiberufler im Bereich Softwareentwicklung Von der PLC und Robotik zu VB.NET & C#, vorrangig WPF und UWP

    • Als Antwort markiert AlexanderRi Dienstag, 8. September 2020 07:39
    Montag, 7. September 2020 07:07
  • Ok dann habe ich die Aufgabenstellung falsch verstanden.

    Man könnte dann 2 Abfragen machen und diese an Math.Max übergeben. Ich persönlich würde dies mit eigenen Schleifen lösen. Meiner Meinung nach ist dies keine Aufgabe für Linq.

    Aber vielleicht hat jemand andere eine besser Idee


    Gruß Thomas
    13 Millionen Schweine landen jährlich im Müll
    Dev Apps von mir: UWP Segoe MDL2 Assets, UI Strings

    • Als Antwort markiert AlexanderRi Dienstag, 8. September 2020 07:39
    Sonntag, 6. September 2020 14:16
  • Hallo,

    versuchs mal mit der folgenden Codesequenz:

    public class Test : IEnumerable<Test>
    {
        public int ID { get; set; }
    
        public List<Test> SubIDs { get; set; }
    
        public Test()
        {
            SubIDs = new List<Test>();
        }
    	
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    	
    	public IEnumerator<Test> GetEnumerator()
    	{
    		yield return this;
    		
    		var subs = SubIDs.SelectMany(x => x);
    		foreach(var x in subs)
    			yield return x;
    	}
    }
    
    private void GetMaxValue()
    {
        List<Test> values = new List<Test>();
    
        var test = new Test { ID = 1 };
        test.SubIDs.Add(new Test { ID = 2 });
        test.SubIDs.Add(new Test { ID = 12 });
        test.SubIDs.Add(new Test { ID = 4 });
        values.Add(test);
    
        test = new Test { ID = 7 };
        test.SubIDs.Add(new Test { ID = 5 });
        test.SubIDs.Add(new Test { ID = 6 });
        test.SubIDs.Add(new Test { ID = 3 });
        values.Add(test);
    
        var max = values.SelectMany(x => x).Select(p => p.ID).Max();
    }
    Hier wird über IEnumerable<T> und SelectMany() der Baum rekursiv durchlaufen.

    VG

    Alpecine


    • Bearbeitet Alpecine Montag, 7. September 2020 10:58
    • Als Antwort markiert AlexanderRi Dienstag, 8. September 2020 07:40
    Montag, 7. September 2020 10:57

Alle Antworten

  • Hallo Alexander,

    Du könntest das so machen

    public class Test
    {
        public int ID { get; set; }
    
        public List<Test> SubIDs { get; set; }
    
        public Test()
        {
            SubIDs = new List<Test>();
        }
    }
    
    private void GetMaxValue()
    {
        List<Test> values = new List<Test>();
    
        var test = new Test { ID = 1 };
        test.SubIDs.Add(new Test { ID = 2 });
        test.SubIDs.Add(new Test { ID = 12 });
        test.SubIDs.Add(new Test { ID = 4 });
        values.Add(test);
    
        test = new Test { ID = 7 };
        test.SubIDs.Add(new Test { ID = 5 });
        test.SubIDs.Add(new Test { ID = 6 });
        test.SubIDs.Add(new Test { ID = 3 });
        values.Add(test);
    
        var max = (from l in values
                   from s in l.SubIDs
                   select s).Max(a => a.ID);
    
    }


    Gruß Thomas
    13 Millionen Schweine landen jährlich im Müll
    Dev Apps von mir: UWP Segoe MDL2 Assets, UI Strings

    Freitag, 4. September 2020 15:37
  • Hallo Thomas,
    Danke für deine Hilfe.

    Deine Lösung sucht nach dem maximalen ID-Wert nur in den Test-Objekten der Liste SubIDs. 
    Es sollen aber auch die ID-Werte der Objekte in der Liste values berücksichtigt werden.
    Somit muss der ID-Wert von den Objekten in zwei Listen (values und SubIDs) verglichen werden.

    Wenn ich das folgende Objekt ändere (ID von 7 auf 88), dann muss die Variable max 88 enthalten und nicht 12.

    test = new Test { ID = 88 };       // 7 auf 88)
    test.SubIDs.Add(new Test { ID = 5 });
    test.SubIDs.Add(new Test { ID = 6 });
    test.SubIDs.Add(new Test { ID = 3 });
    values.Add(test);

    Hast du dafür eine LINQ-Lösung?

    Alexander
    Sonntag, 6. September 2020 10:35
  • Ok dann habe ich die Aufgabenstellung falsch verstanden.

    Man könnte dann 2 Abfragen machen und diese an Math.Max übergeben. Ich persönlich würde dies mit eigenen Schleifen lösen. Meiner Meinung nach ist dies keine Aufgabe für Linq.

    Aber vielleicht hat jemand andere eine besser Idee


    Gruß Thomas
    13 Millionen Schweine landen jährlich im Müll
    Dev Apps von mir: UWP Segoe MDL2 Assets, UI Strings

    • Als Antwort markiert AlexanderRi Dienstag, 8. September 2020 07:39
    Sonntag, 6. September 2020 14:16
  • Hi,

    ich habe mal die Klassen von Thomas genommen und die Abfrage könnte so aussehen:

    var result = values.Concat(values.SelectMany(x => x.SubIDs)).Max(i => i.ID);

    Gruß


    Freiberufler im Bereich Softwareentwicklung Von der PLC und Robotik zu VB.NET & C#, vorrangig WPF und UWP

    • Als Antwort markiert AlexanderRi Dienstag, 8. September 2020 07:39
    Montag, 7. September 2020 07:07
  • Hallo,

    versuchs mal mit der folgenden Codesequenz:

    public class Test : IEnumerable<Test>
    {
        public int ID { get; set; }
    
        public List<Test> SubIDs { get; set; }
    
        public Test()
        {
            SubIDs = new List<Test>();
        }
    	
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    	
    	public IEnumerator<Test> GetEnumerator()
    	{
    		yield return this;
    		
    		var subs = SubIDs.SelectMany(x => x);
    		foreach(var x in subs)
    			yield return x;
    	}
    }
    
    private void GetMaxValue()
    {
        List<Test> values = new List<Test>();
    
        var test = new Test { ID = 1 };
        test.SubIDs.Add(new Test { ID = 2 });
        test.SubIDs.Add(new Test { ID = 12 });
        test.SubIDs.Add(new Test { ID = 4 });
        values.Add(test);
    
        test = new Test { ID = 7 };
        test.SubIDs.Add(new Test { ID = 5 });
        test.SubIDs.Add(new Test { ID = 6 });
        test.SubIDs.Add(new Test { ID = 3 });
        values.Add(test);
    
        var max = values.SelectMany(x => x).Select(p => p.ID).Max();
    }
    Hier wird über IEnumerable<T> und SelectMany() der Baum rekursiv durchlaufen.

    VG

    Alpecine


    • Bearbeitet Alpecine Montag, 7. September 2020 10:58
    • Als Antwort markiert AlexanderRi Dienstag, 8. September 2020 07:40
    Montag, 7. September 2020 10:57