【问题标题】:Let Query syntax in Method Syntax?让方法语法中的查询语法?
【发布时间】:2018-03-06 23:43:26
【问题描述】:

我正在尝试将 Linq Query 示例翻译成 Lambda,但在翻译 Let 子句时遇到问题。

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;

此示例按预期工作:

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

查询和上面的例子都可以通过以下方式打印:

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

但我想让它更具可读性并以某种方式提取条件,所以我尝试了这个(从这篇帖子 LINQ Let operator with lambda syntax 得到这个想法)但是它

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());

现在打印有点变了,我需要具体说一下我要打印数字。

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

将此查询转换为 lambda 语法的正确方法是什么?以某种方式“提取”条件?

【问题讨论】:

  • 仅供参考,这是查询语法,您想将其转换为方法语法。

标签: c# linq lambda


【解决方案1】:

你可以像这样重写你的 GroupBy,所以它显示你的“让”中间步骤,结果相同:

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

基本上,只要参数和返回类型正确,您就可以使用复杂函数作为 lambda 表达式。

在这种情况下,您不能使用简化的语法,所以它有点冗长,您必须像通常的方法一样使用return 语句和括号。

类似问题的更详细解释在这里:

linq "let" translation

【讨论】:

  • 谢谢,我什至没有想到尝试在 GroupBy 方法中进行操作 :)
  • @Darkbound,是的(在我上面链接的问题中更详细),你可以有任何函数方法作为你的 lambda,你只需要在这种情况下清楚地使用 return 语句.但最后,您可以看到这只是一个 lambda,它采用 n 并返回一个 string,所以一切都很好!很高兴它有帮助。
  • 所以基本上每当我想在 Lambda(method) 语法中使用 let 时,我只需要在 Linq 方法中扩展匿名方法(就像我们在这里对组所做的那样)并创建我的 let (var ) 变量并在最后返回正确的类型?
  • @Darkbound 是的,完全正确!通常的符号x => expression 只是单行函数x => { return expression; } 的语法糖(简写),没有什么能阻止您在返回之前用几行代码定义更复杂的函数。您还可以在其他地方定义您的 lambda,并传递 Func<T1, T2> 对象引用,如果这有助于您更清楚或在多个查询中重复使用相同的对象。
  • 我最后一句话的例子:Func<int, string> evenOrOdd = (int n) => n % 2 == 0 ? "Even" : "Odd";,然后 GroupBy 部分可以简单地写成这样:arrayOfNumbers.GroupBy(evenOrOdd)。我发现它在某种程度上更具可读性,特别是如果您有多个使用相同逻辑的查询。
猜你喜欢
  • 2013-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-09
  • 1970-01-01
  • 2015-06-15
  • 1970-01-01
相关资源
最近更新 更多