.NETs Select(映射)和Aggregate(减少)的命名背后的原因是什么?


17

在其他编程语言中,我见过Map和Reduce,它们是函数式编程的基石。我找不到LINQ为什么具有Aggregate(与Reduce)和Select(与Map)相同的任何理由或历史?

我问的原因是我花了一段时间才明白这是一回事,我很好奇这是什么原因。




另一方面,我很想知道命名选择“ Map”和聚合“ Reduce”背后的原因。

Answers:


32

这主要归结于LINQ的历史。

LINQ 最初旨在像SQL一样,并且(尽管不是专门地)用于连接到SQL数据库。这导致其许多术语都基于SQL。

所以,“选择”从SQL来select声明,而“总”从SQL聚合函数来(例如countsumavgminmax)。

对于那些质疑LINQ最初与SQL的关联程度的人,我将参考(例如)微软有关Cω的文章,这是微软研究院设计的一种语言,似乎是大多数LINQ基础工作的地方在将它们添加到C#和.NET之前。

例如,考虑有关CωMSDN文章,其中说:

Cω中的查询运算符

Cω在C#语言中添加了两大类查询运算符:
-基于XPath的运算符,用于按名称或类型查询对象的成员变量。
-基于SQL的运算符,用于执行复杂的查询,包括对来自一个或多个对象的数据进行投影,分组和联接。

至少据我所知,基于XPath的运算符从未被添加到C#中,仅留下了被证明(在LINQ存在之前)直接基于SQL的运算符。

现在,LINQ与Cω中基于SQL的查询运算符并不完全相同。特别是,LINQ遵循C#的基本对象,并且函数调用语法比Cω更紧密。Cω查询甚至更严格地遵循SQL语法,因此您可以编写如下内容(同样,直接从上面链接的文章中得出):

 rows = select c.ContactName, o.ShippedDate
      from c in DB.Customers
      inner join o in DB.Orders
      on c.CustomerID == o.CustomerID;

是的,同一篇文章确实专门讨论了使用基于SQL的查询来查询来自实际SQL数据库的数据:

若要连接到Cω中的SQL数据库,它必须作为托管程序集(即.NET库文件)公开,然后由应用程序引用。通过使用sql2comega.exe命令行工具或Visual Studio中的“ 添加数据库架构...”对话框,可以将关系数据库作为托管程序集暴露给Cω 。Cω使用数据库对象表示服务器托管的关系数据库。甲数据库对象具有用于每个表或视图,以及用于在数据库中找到的每个表值函数的方法的公共属性。要查询关系数据库,必须将表,视图或表值函数指定为一个或多个基于SQL的运算符的输入。

下面的示例程序和输出显示了使用基于SQL的运算符查询Cω中的关系数据库的一些功能。本示例中使用的数据库是Microsoft SQL Server附带的示例Northwind数据库。在示例中使用的名称DB指的是使用sql2comega.exe生成的Northwind.dll程序集的Northwind命名空间中Database对象的全局实例。

因此,是的,从一开始(或什至在开始之前,取决于您的观点),LINQ就明确基于SQL,并且专门用于允许访问SQL数据库中的数据。


5
我不同意LINQ是为SQL查询发明的。LINQ基于Cω中的查询操作,而又从X♯继承了它们,X♯基于旧的Haskell论文。请注意,Haskell论文的作者之一是Erik Meijer,此后也参与了X♯和Cω的设计,并且当然是LINQ的设计师。从一开始就很明显,LINQ可用于查询各种内容,而不仅仅是SQL(从第一天开始,它就随LINQ-to-SQL,LINQ-to-XML和LINQ-to-Objects一起提供了查询。其次是...
约尔格W¯¯米塔格

4
LINQ-to-Entities),实际上比查询要多得多(它基本上是通用的Monad Comprehension语法)。它是为使SQL(和XQuery)程序员熟悉而设计的,但当然不限于此。同样,Scala的Monad Comprehensions看起来像是for循环,Haskell的外观像是C风格的命令性代码块,因此Scala称其为monadic运算flatMap,而Haskell则return出于相同的原因:与防止出现的“幻觉”相适应(前)命令式程序员。
约尔格W¯¯米塔格

2
@JörgWMittag:参见编辑后的答案。我相信Microsoft的文档支持我的陈述。
杰里·科芬

3
+1用于实际证明答案,而不是一厢情愿的猜测。您无法获得比Microsoft本身更权威的信息。
milleniumbug

谢谢你,先生!这正是我希望收到的答案。
Tx3

8

.NET中的LINQ方法

source.Where(x => condition)
      .Select(x => projection)

被命名为与C#(和VB.NET)中的LINQ查询语法一致

from x in source
where condition
select projection

旨在让熟悉SQL的人熟悉

SELECT projection
FROM source x
WHERE condition

2

对我而言,“选择并汇总”更有意义。随着实体成为.Net中查询和处理数据的主要方法,Linq越来越多地被可能习惯于通过SQL处理数据的开发人员使用。因此,对于那些开发人员来说,使用“选择”之类的词更有意义,因为它们是他们惯用的关键字。


4
“越来越多的开发人员可能习惯于通过SQL处理数据”,我对此表示怀疑。我与之合作并赞扬Entity Framework的那个家伙不知道他需要INNER JOIN在Entity Framework不能选择的情况下完成一天。可能恰恰相反。每天越来越多的人积极使用LINQ来避免编写SQL。熟悉SQL的人可能只会在SQL上做更多的事情。
jpmc26 2016年

1
那不是我所看到的。我主要通过最近的工作搜索发现,曾经使用存储过程处理数据的开发人员开始在控制器中进行所有脚本编写。对我来说,Linq使用熟悉的表达式会有所帮助。我毫不怀疑“与您一起工作的人”就是这种情况,但这不是我的经验。
克里斯汀
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.