1

I'm reading C# In Depths to try and better understand the language. I've used simple lambda expressions before with a single parameter and have become familiar with them. The part I'm struggling with is films.Sort((f1, f2) => f1.Name.CompareTo(f2.Name)); to sort the list. From what I've been able to figure out the lambda expression evaluates to IComparer<Film> when I tried to add f3 to it. The method being called IComparer.Compare Method (T, T) determines the items order.

The second parameter makes me want to say that it's comparing the Nth and Nth+1 film in the list and doing that from 0 through films.Count-1. Is this correct? If not, what part am I mistaken on. I wan't to avoid assuming incorrectly and avoid unintended errors.

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var films = GetFilms();

        Action<Film> print = film => Console.WriteLine("Name={0}, Year={1}", film.Name, film.Year);

        Console.WriteLine("All films");
        films.ForEach(print);

        Console.WriteLine();
        Console.WriteLine("Old films");
        films.FindAll(film => film.Year < 1960).ForEach(print);

        Console.WriteLine();
        Console.WriteLine("Sorted films");
        films.Sort((f1, f2) => f1.Name.CompareTo(f2.Name));
        films.ForEach(print);
    }

    class Film
    {
        public string Name { get; set; }
        public int Year { get; set; }
    }

    static List<Film> GetFilms()
    {
        return new List<Film>
        {
            new Film { Name = "Jaws", Year = 1975 },
            new Film { Name = "Singing in the Rain", Year = 1952 },
            new Film { Name = "Some like it Hot", Year = 1959 },
            new Film { Name = "The Wizard of Oz", Year = 1939 },
            new Film { Name = "It's a Wonderful Life", Year = 1946 },
            new Film { Name = "American Beauty", Year = 1999 },
            new Film { Name = "High Fidelity", Year = 2000 },
            new Film { Name = "The Usual Suspects", Year = 1995 }
        };
    }
}

2 Answers 2

2

You can't tell from the method signature how many times the argument will be used. I could write a method Foo(Func<string, string>) that never called its argument.

However, since this is a sorting method, it's not enough to iterate once over the list. There are lots of different sorting algorithms, but they tend to use O(n log(n)) comparisons. In other words, doubling the length of the list sorted will result in slightly more than double the calls to your lambda function.

If you want to see what actually happens when it's running, add some logging!

films.Sort((f1, f2) => 
{
    Console.WriteLine("Comparing ${f1.Name} to ${f2.Name}");
    return f1.Name.CompareTo(f2.Name);
});
Sign up to request clarification or add additional context in comments.

2 Comments

Followed your suggestion and found out, in this instance, it's using a selection sort. Seeing I could use { ... } after => operator made sense. Thanks mightily.
@IvenBach Glad it worked! There is a subtle difference when you use the braces; you have to return the final value.
2

Actually you can use LINQ for sorting elements on any type that implements IEnumerable<T> interface like List<T> type:

// This will order the films by their name.
var result1 =
    films
        .OrderBy(film => film.Name)
        .ToList();

// This will order the films first by Year in descending order and 
// then by Name in ascending order.
var result2 =
    films
        .OrderByDescending(film => film.Year)
        .ThenBy(film => film.Name)
        .ToList();

There is also a ThenByDescending() method you can use and also you can create a longer chain from these methods if needed.

The thing is that here you should select only one property at a time in the lambda expression.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.