Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Using LINQ to filter each Object with Max Value in List of Objects [duplicate]

Tags:

c#

list

linq

max

I'm not just trying to find the maximum value in a list. I'm trying to find each Object that has a maximum value for a given string title. The end result will be a list object with only the objects that have maximum value.

I cannot seem to get my LINQ statement to work. It keeps pulling the maximum integer value rather than pull the object that has the maximum integer value.

Also, if there is a more efficient route rather than looping through the list - I'm all for it.

Any help is greatly appreciated

EDIT This is not a duplicate of this link suggested by Servy
if @Servy would focus on reading the text instead of comparing titles he/she would see that this is completely different. That link wanted to find a single max value of an object. This is not what I'm asking.

Here's my current code:

public class Prop {     
    public string title {get;set;}
    public int val {get;set;}       
}   

public static void Main()
{
    List<Prop> list = new List<Prop>();
    list.Add(newProp("voltage", 7));
    list.Add(newProp("voltage", 24));
    list.Add(newProp("systemconfiguration", 2451));
    list.Add(newProp("systemunit", 0));
    list.Add(newProp("systemunit", 15));
    list.Add(newProp("voltage", 0));


    List<Prop> newList = new List<Prop>();

    foreach (var p in list) {
        var newP = list.Select(r => r).Where(t => t.title == p.title).Max(v => v.val);  
        Console.WriteLine(newP.ToString());  
        //This is returning the maximum integer found per title

       //newList.Add(newP);    <---- I cannot do this because newP is an Int
    }

    /*
       I need the output of this example to only contain:

           voltage, 24
           systemconfiguration, 2451
           systemunit 15

      As these are the maximum values per title in the list of objects.

    */

}

public static Prop newProp(string t, int v) {
    Prop item = new Prop();
    item.title = t;
    item.val = v;
    return item;    
}
like image 435
bagofmilk Avatar asked Sep 05 '25 13:09

bagofmilk


2 Answers

You can achieve the desired result at once with a simple GroupBy and subsequent ordering within each group:

var highestByTitle = list
    .GroupBy(t => t.title)
    .Select(g => g.OrderByDescending(t => t.val).First())
    .ToList();

Demo.

like image 172
Sergey Kalinichenko Avatar answered Sep 11 '25 04:09

Sergey Kalinichenko


The Max function returns a single value from the attribute that is used inside the function that is passed. Try using OrderByDescending instead:

var newP = list.Select(r => r).Where(t => t.title == p.title).OrderByDescending(v => v.val).First();
like image 37
Kevin K. Avatar answered Sep 11 '25 05:09

Kevin K.