Darkbound
Darkbound

Reputation: 3434

Let Query syntax in Method Syntax?

I am trying to translate a Linq Query example into Lambda and I am having trouble translating the Let clause.

var numbers = from n in arrayOfNumbers
              orderby n
              let evenOrOdd = (n % 2 == 0) ? "Even" : "Odd"
              group n by evenOrOdd into nums
              orderby nums.Count()
              select nums;

This example does work as intended:

var numbers = arrayOfNumbers.OrderBy(n => n)
                            .GroupBy(n => (n % 2 == 0) ? "Even" : "Odd")
                            .OrderBy(k => k.Count());

Both the query and the example above can be printed the following way:

foreach (var item in numbers)
{
    Console.WriteLine($"{item.Key}");
    foreach (var i in item)
    {
        Console.WriteLine($"  {i}");
    }
}

But I wanted to make it a bit more readable and extract the condition somehow, so I tried this (got the idea from this post LINQ Let operator with lambda syntax) but it

var numbers = arrayOfNumbers.OrderBy(n => n)
                            .Select(evenOrOdd => new
                            {
                                Number = evenOrOdd,
                                Key = (evenOrOdd % 2 == 0) ? "Even" : "Odd"
                            })
                            .GroupBy(n => n.Key)
                            .OrderBy(k => k.Count());

And now the printing is a bit changed, I need to specificly say that I want to print the Number.

foreach (var item in numbers)
{
    Console.WriteLine($"{item.Key}");
    foreach (var i in item)
    {
        Console.WriteLine($"  {i.Number}");
    }
}

What is the correct way to translate this query into lambda syntax with the condition somehow "extracted"?

Upvotes: 2

Views: 1447

Answers (1)

Pac0
Pac0

Reputation: 23149

You can rewrite your GroupBy like that, so it shows your 'let' intermediary step, with indentical result :

var numbers = arrayOfNumbers
    .OrderBy(n => n)
    .GroupBy(n => {
         var evenOrOdd = (n % 2 == 0);
         return evenOrOdd ? "Even" : "Odd";
    })
    .OrderBy(k => k.Count());

Basicaly, you can use complex function as your lambda expression, as soon as the parameter and return type are correct.

In this case, you can't use the simplified syntax so it's a bit more verbose, you have to use the return statement and brackets like your usual methods.

A more detailed explanation in a similar question is here :

linq "let" translation

Upvotes: 1

Related Questions