Search code examples
listsortingbeef

How do I sort a List given an ordering method or lambda?


If I have a method or lambda to sort a List<T> e.g. using the spaceship operator (From the documentation: x <=> y - results is negative if x < y, zero if x == y, positive if x > y), how can I sort a list using that method?

There is a Sort(Comparison<T>) method on List<T> but the documentation does not explain how to use it.

For instance, suppose I want to sort a list of strings by their lengths, first in ascending order, then in descending order using a method and a lambda:

using System;
using System.Collections.Generic;

namespace test
{
    class Program
    {
        public static int ascendingMethod (String lhs, String rhs)
        {
            return lhs.Length <=> rhs.Length;
        }

        public static void Main()
        {
            function int(String lhs, String rhs) descendingLambda = (lhs, rhs) => 
                    rhs.Length <=> lhs.Length;

            let list = scope List<String>();
            list.Add("2Foobar");
            list.Add("1Fooba");
            list.Add("3Foob");

            //sort using Descending lamdba
            for(let s in list)
            {
                Console.WriteLine(s);
            }

            // sort using Ascending method
            for(let s in list)
            {
                Console.WriteLine(s);
            }
        }
    }
}

Solution

  • You can assign the lambda or bind a Comparison<T> to the method, then use List<T>.Sort(Comparison<T>).

    In the String example, it could look like this:

    using System;
    using System.Collections.Generic;
    
    namespace test
    {
        class Program
        {  
            public static int ascendingMethod (String lhs, String rhs)
            {
                return lhs.Length <=> rhs.Length;
            }
    
            public static void Main()
            {
                Comparison<String> descendingLambdaComparison = scope (lhs, rhs) => 
                        rhs.Length <=> lhs.Length;
                Comparison<String> ascendingMethodComparison = scope => ascendingMethod;
    
                let list = scope List<String>();
                list.Add("2Foobar");
                list.Add("1Fooba");
                list.Add("3Foob");
    
                list.Sort(descendingLambdaComparison);
                for(let s in list)
                {
                    Console.WriteLine(s);
                }
    
                list.Sort(ascendingMethodComparison);
                for(let s in list)
                {
                    Console.WriteLine(s);
                }
            }
        }
    }