“折叠”LINQ 扩展方法在哪里?

Posted

技术标签:

【中文标题】“折叠”LINQ 扩展方法在哪里?【英文标题】:Where is the "Fold" LINQ Extension Method? 【发布时间】:2010-11-16 20:58:46 【问题描述】:

我在MSDN's Linq samples 中找到了一个我想使用的名为 Fold() 的简洁方法。他们的例子:

double[] doubles =  1.7, 2.3, 1.9, 4.1, 2.9 ; 
double product = 
     doubles.Fold((runningProduct, nextFactor) => runningProduct * nextFactor); 

不幸的是,无论是在他们的示例中还是在我自己的代码中,我都无法对其进行编译,而且我在 MSDN 中的其他任何地方(例如 Enumerable 或 Array 扩展方法)都找不到提到此方法的地方。我得到的错误是一个普通的“对此一无所知”的错误:

error CS1061: 'System.Array' does not contain a definition for 'Fold' and no 
extension method 'Fold' accepting a first argument of type 'System.Array' could 
be found (are you missing a using directive or an assembly reference?)

我正在使用我认为来自 Linq 的其他方法(例如 Select() 和 Where()),并且我正在“使用 System.Linq”,所以我认为这一切都可以。

这种方法在 C# 3.5 中是否真的存在,如果存在,我做错了什么?

【问题讨论】:

查看您引用的示例页面上的面包屑线索* - 它将 C# 3 称为未来产品。未来的产品通常会在发货前发生变化。像提到的其他人一样,请参阅 Enumerable.Aggregate 并玩得开心。 :) *Visual C# 开发者中心 > 主页 > 产品信息 > 未来版本 > 101 LINQ 示例 > 聚合运算符 【参考方案1】:

您将需要使用Aggregate 扩展方法:

double product = doubles.Aggregate(1.0, (prod, next) => prod * next);

请参阅MSDN 了解更多信息。它允许您指定 seed,然后指定一个表达式来计算连续值。

【讨论】:

应该注意的是,您也不必拥有种子。如果您调用没有种子的重载,则列表中的第一个元素将用作初始聚合值,并且只有在达到第二个元素时才会调用 Func。见:msdn.microsoft.com/en-us/library/vstudio/… 如果我理解正确,它不是折叠:/折叠应该接受不同类型的两个参数。例如。第一个参数可以使用字符串,第二个参数可以使用ToString(),因此返回整个容器的文本表示。 @Hi-Angel,不,这个例子实际上是一个折叠。 <double> 类型参数只是由编译器自动推断,因此没有必要。 @Hi-Angel、pelem 可以是您喜欢的任何类型。请参阅this example 中使用的this overload @kdbanman errr,⁺¹,这真的很有趣,为什么过去它对我不起作用……:/你说得对,它确实起作用。【参考方案2】:

Fold(又名 Reduce)是函数式编程的标准术语。无论出于何种原因,它在 LINQ 中被命名为 Aggregate。

double product = doubles.Aggregate(1.0, (runningProduct, nextFactor) => runningProduct* nextFactor);

【讨论】:

聚合是 OO 和 SQL 领域中更熟悉的术语。 不知道 CREATE AGGREGATE 关键字 (msdn.microsoft.com/en-us/library/ms182741.aspx) 每天学习新东西。 有趣的是,我从未听说过 SQL 之外的“聚合”。 WP 有几十种语言的列表en.wikipedia.org/wiki/Fold_(higher-order_function),而 C# 是唯一一种将其称为“聚合”的语言。 “Reduce”显然是赢家,其次是 ML 系列的“Fold”,以及 Smalltalk 和朋友的“Inject”。 名称是其功能的问题;它是如何实现的无关紧要。 FWIW,左折叠在可能的情况下迭代实现......在函数式语言中通常通过尾递归。而且 C# 没有正确的折叠,这在一定程度上是因为选择了一个愚蠢的名称——尽管没有为“map”选择“select”那么糟糕——并且忽略了现有的函数式技术。至于聚合是 OO 领域中更熟悉的术语……不,根本不是。 说句公道话,我不认为这是微软对现有函数式技术或术语的漠视,而是它对数据库访问和 SQL 术语的定位,很多企业程序员可能比函数式编程术语更熟悉.

以上是关于“折叠”LINQ 扩展方法在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

动态 linq:创建生成 JSON 结果的扩展方法

Linq 中 Enumerable.Zip 扩展方法有啥用?

LINQ中的扩展方法

创建 Where 查询的 LINQ 扩展方法

Linq 扩展方法在 Visual Studio 2015 即时窗口中不可用

针对 SQL 后端的 LINQ 的可扩展包含方法