4

This is a really simple question, I would imagine, for someone who knows lambda well. I am just now learning it and have run across one expression that doesn't make sense to me.

From what I understand, lambda expressions pass in the variable specified on the left side and runs the code on the right. For instance

myFunction = x => x + x;

so myFunction(2) would return 4.

Anyhow, I was looking at a linq query on here and saw this:

IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0).OrderBy(n => n);

The n => n ... what does that do? Why not just say OrderBy(n)? All you are doing it passing n into a function that just returns n. >_> What's happening here?

2
  • 2
    Suppose you have a function int F(int x) { return x; }, then you could use .OrderBy(F) Commented May 30, 2013 at 17:58
  • 1
    In more lay language: you have to tell OrderBy which key or property you want to use to sort. MSDN example: IEnumerable<Pet> query = pets.OrderBy(pet => pet.Age);. Saying OrderBy(Pet) wouldn't be helpful since OrderBy doesn't know how to arrange a Pet. Commented May 30, 2013 at 18:04

3 Answers 3

9

The n => n ... what does that do?

It just maps any value to itself. It's an identity function.

Why not just say OrderBy(n)?

Because n isn't a variable in scope - it wouldn't be valid to call it like that. That's not a lambda expression, so it would just try to use n as a normal method argument.

Your code is just trying to say "order this sequence by the whole of each element" rather than projecting each element to some other value, but there's no way of saying that directly.

OrderBy requires a projection from the element type to the ordering key type - it's just that in this case we want the identity projection.

You could write your own extra extension method:

public static IEnumerable<T> OrderNaturally<T>(this IEnumerable<T> source)
{
    return source.OrderBy(item => item);
}

And then change your original statement to:

IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0).OrderNaturally();

if you found that more readable.

Alternatively, you could create a Functions class with some useful static readonly fields:

public static class Functions<T>
{
    public static readonly Func<T, T> Identity = x => x;
    public static readonly Func<T, T> DefaultValue => x => default(T);
    public static readonly Func<T, string> ToString = x => x == null ? null : x.ToString();
    ...
}

Then:

IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0)
                                    .OrderBy(Functions<int>.Identity)

I don't think I would do that... I'm just suggesting things to think about :)

Sign up to request clarification or add additional context in comments.

2 Comments

If you change it Order, then you can actually have it use fewer characters to declare throughout your code, while still having decent readability. However, if you wanted to have a similar extension method for ThenBy, a Then method is, to me, not readable, while a ThenNaturally would be perfectly readable.
@TimS.: No, I wouldn't call it just Order - that doesn't explain it clearly enough in my view.
4

Let's break this down:

numbers

This is a collection of integers.

.Where(num => num % 2 == 0)

This is saying "find me all items in my collection where my number modulus 2 = 0".

.OrderBy(n => n);

This is then ordering the list. Because the list is of integers, and the specified item is an integer, it will be ordered numerically, lowest to highest.

The reason you need n => n is because you could sort by something other than the value. Say, for example, the length of the item as a string

.OrderBy(n => n.ToString().Length)

Obviously, for integers, this serves no purpose. But for other data types, like classes, this is very helpful.

2 Comments

Thank you for the answers! Yours and Jon Skeet's were both extremely informative and fit my needs perfectly, but you got first post so you get the answer!
@user1548103: Actually my post was about a minute earlier, but I wouldn't recommend using time as the way of determining which answer to accept anyway. It should be the most helpful answer, in whatever way you choose to decide that. (I'm not suggesting you switch accepted answers - I'm just suggesting that time isn't the best metric to use.)
0

n => n means that the function accepts one argument as it's input and returns it's input as the return value.

Why not just say OrderBy(n)

How would you know that n is a lambda? What indication is there that it's a function? If you had a function, named n, that accepted an integer and returned that same integer, then you could do that, but my guess is that isn't what you were thinking of.

I know you didn't ask it but:

Is there some alternate syntax that the C# compiler team could have used to cover the special case of the "identity lambda"?

(An "identity lambda" is the technical term for a function that only returns it's one input value).

Yes. They could have. They didn't, probably because they just didn't consider it worth the time/effort, given that writing an identity function is easy enough without any special syntax.

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.