Runtime: Add LINQ methods SelectMin() and SelectMax()

Created on 5 Aug 2020  路  14Comments  路  Source: dotnet/runtime

_This issue has been moved from a ticket on Developer Community._


Let's say you have a list of objects and you want to get the object / entry with the highest or lowest value. At the moment there are no direct methods for this.

There are only the methods Min() and Max() which return the actual highest or lowest value, but not the object of it.

Therefore I'd suggest the LINQ methods SelectMin() and SelectMax().

Both are pretty straightforward. It selects the item with the lowest (min) or highest (max) value.

Example:

internal class Program
{
    private static void Main(string[] args)
    {
        var weapons = new List<Weapon>
        {
            new Weapon { Name = "Test1", Description = "test desc1", Power = 11},
            new Weapon { Name = "Test2", Description = "test desc2", Power = 22},
            new Weapon { Name = "Test3", Description = "test desc3", Power = 33},
            new Weapon { Name = "Test4", Description = "test desc4", Power = 44},
            new Weapon { Name = "Test5", Description = "test desc5", Power = 55},
        };

        var highestPower = weapons.Max(x => x.Power); // returns 55
        var mostPowerfulWeapon = weapons.SelectMax(x => x.Power); // Should return the last weapon object with Power == 55
        var noobyWeapon = weapons.SelectMin(x => x.Power); // should return the first weapon with Power == 11
    }
}

internal class Weapon
{
    public string Name { get; set; }
    public string Description { get; set; }
    public int Power { get; set; }
}

At the moment, you could use Max() before and then use the result for a First() call or use the method Aggregate(). Both solutions have overhead and are harder to read than my suggested solution.


Original Comments

Feedback Bot on 6/22/2020, 00:04 AM:

Thank you for taking the time to provide your suggestion.  We will do some preliminary checks to make sure we can proceed further.  We'll provide an update once the issue has been triaged by the product team.

Dean Goddard on 6/26/2020, 05:23 AM:

It's one of the hardest things to do with normal SQL getting access to the rest of the row that where a column has the highest/lowest value. So I support this idea for LINQ.

api-suggestion area-System.Linq

Most helpful comment

@hez2010 - A better workaround would be OrderBy(<whatever>).First(), especially since we optimized that internally to avoid the otherwise necessary O(n log n) time and O(n) additional space.

All 14 comments

Tagging subscribers to this area: @eiriktsarpalis
See info in area-owners.md if you want to be subscribed.

AKA MinBy/MaxBy.
Duplicate of:

14753

19522

27687

32471

Is not Select / GroupBy / ... more applicable to "map" style operations while Where / First / ... are focused on the "filter" style operations? With the use case above I would understand that this is more a FirstMax situation?

@tthiery - Which is why this operation is often named MaxBy. (Due to implementation details it may consistently return first/last, but that maybe shouldn't be relied upon, and can't if implemented for PLINQ).

Dean Goddard - while this isn't necessarily easy to do currently in LINQ-to-SQL, there's a number of easy ways to do this in raw SQL, depending on your exact needs (and which specific RDBMS you're using). Note that LINQ-to-SQL would have to be set up to return the optimized SQL anyways, which may not always be possible.

Is not Select / GroupBy / ... more applicable to "map" style operations while Where / First / ... are focused on the "filter" style operations? With the use case above I would understand that this is more a FirstMax situation?

I suggested this addition and you are right, FirstMax() and FirstMin() would be a better naming for that. I named it after a natural speaking perspective, where you want to select an entry with the highest or lowest value, which suggest, that there is only one entry (=first).

there's a number of easy ways to do this in raw SQL

Sure, you can always work with raw SQL, but personally I like the concept of LINQ and would prefer a simple method for that use case.

Actually you can OrderBy then Take(1) and Select.

@hez2010 - A better workaround would be OrderBy(<whatever>).First(), especially since we optimized that internally to avoid the otherwise necessary O(n log n) time and O(n) additional space.

I suggested this addition and you are right, FirstMax() and FirstMin() would be a better naming for that. I named it after a natural speaking perspective, where you want to select an entry with the highest or lowest value, which suggest, that there is only one entry (=first).

@Zerotask I disagree - what would LastMax() and LastMin() be, and how would they differ from FirstMax() and FirstMin()? I think MaxBy and MinBy are best.

@NetMage I disagree with you. FirstMin() is related to the First() method which intends that there is only 1 result. MinBy() and MaxBy() are possible alternative names but it's a personal preference. I think MinBy() rather intends that you get the lowest value and not 1 result with a lowest value.

@Zerotask - In pretty much all of computer programming, max and min operations are always understood as "a max" and "a min", because there can always be duplicate values. Whether it returns first/last of the duplicates is a (rarely important) implementation detail. Getting "all results with the minimum value" is a much more difficult operation.

@hez2010 - A better workaround would be OrderBy(<whatever>).First(), especially since we optimized that internally to avoid the otherwise necessary O(n log n) time and O(n) additional space.

From the code https://github.com/microsoft/referencesource/blob/3b1eaf5203992df69de44c783a3eda37d3d4cd10/System.Core/System/Linq/Enumerable.cs#L2547 it is not obvious to me. What am I missing ?

EDIT:
OK sorry, I picked the wrong repo and missed https://github.com/dotnet/runtime/blob/e7204f5d6fcaca5e097ec854b3be6055229fc442/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.SpeedOpt.cs#L163 in the correct one.

@ilelann - I've been bitten by that too, especially since search engines seem to index the reference source, but not the git repository (as much) - for obvious reasons.

Duplicate of #27687.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

omajid picture omajid  路  3Comments

nalywa picture nalywa  路  3Comments

omariom picture omariom  路  3Comments

chunseoklee picture chunseoklee  路  3Comments

btecu picture btecu  路  3Comments