Reputation: 3434
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
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 :
Upvotes: 1