您将如何使用SelectMany实现LINQ方法?

时间:2013-10-23 13:17:17

标签: c# functional-programming system.reactive linq

   Erik Meijer喜欢指出每个LINQ函数实际上都可以由SelectMany实现;其他一切只是一种便利。

这就是Eric Lippert says answering a question about monads,但我听说Erik Meijer在其他关于LINQ和Rx的视频中说过这个。 (简单地说,Erik Meijer是创建LINQ和Rx的人)

我想知道如何使用SelectMany实现一些最常用的LINQ函数? 暂时忽略性能,让我们专注于优雅和简洁。

  • 其中
  • 选择
  • 第一
  • 取(n)的
  • TakeWhile
  • 的GroupBy
  • 排序依据
  • 邮编
  • 其他...

2 个答案:

答案 0 :(得分:1)

要记住的主要内容是SelectMany适用于IEnumerable并使用可以访问当前项及其索引的lambda表达式返回IEnumerable。因此,您可以采取任何措施来转换结果,并可以访问当前项目或其索引:

  • 决定要保留或丢弃的元素(WhereFirstTakeSkipTakeWhile
  • 更改元素并返回新元素(Select
  • 做其他的东西? (GroupBy,说实话,我不知道如何在没有经过深思熟虑的情况下实现这一点)

这个简单的Where示例将清楚地说明其中有多少可以轻松完成:

SomeList.SelectMany(x =>
    ShouldBeIncluded(x) ?
        Enumerable.Repeat(x, 1) :
        Enumerable.Empty<AClass>();
    );

编辑 - Tim Schmelter在评论中发表的伟大link再次证明了Jon Skeet已经做得更清洁了:

return Enumerable.Repeat(x, ShouldBeIncluded(x) ? 1 : 0;

答案 1 :(得分:0)

好吧,这将返回一个{0},其中包含零个或一个元素,优于零:

Enumerable<T>

看不到如何仅使用public static IEnumerable<T> FirstOrDefault<T>(this IEnumerable<T> source) { return source.SelectMany((t, index) => Enumerable.Repeat(t, index == 0 ? 1 : 0)); } 返回T