15

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

这是Eric Lippert 在回答有关 monads 的问题时所说的,但我在其他有关 LINQ 和 Rx 的视频中听到 Erik Meijer 这么说。(简单地说,Erik Meijer 是创建 LINQ 和 Rx 的人)

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

  • 在哪里
  • 选择
  • 第一的
  • 取(n)
  • TakeWhile
  • 通过...分组
  • 排序依据
  • 压缩
  • 其他...
4

2 回答 2

2

要记住的主要一点是,它SelectMany适用于IEnumerable并返回一个IEnumerable使用 lambda 表达式,该表达式可以访问当前项目及其索引。因此,您可以做任何事情来通过访问当前项目或其索引来转换结果:

  • 决定保留或丢弃哪些元素 ( Where, First, Take, Skip, TakeWhile)
  • 更改元素并返回新元素 ( Select)
  • 做其他事情?(GroupBy,老实说,我不知道我会如何不假思索地实现它)

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

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

编辑 - Tim Schmelter 在评论中发布的精彩链接再次证明 Jon Skeet 已经做得更干净了:

return Enumerable.Repeat(x, ShouldBeIncluded(x) ? 1 : 0;
于 2013-10-23T13:36:54.153 回答
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));
}

看不到如何只返回一个Twith SelectMany

于 2013-10-23T13:43:30.103 回答