码迷,mamicode.com
首页 > 其他好文 > 详细

12.3.2.2 使用查询和序列表达式

时间:2015-01-23 21:39:30      阅读:290      评论:0      收藏:0      [点我收藏+]

标签:f#   函数编程   实用函数编程   序列表达式   查询表达式   

12.3.2.2 使用查询和序列表达式

 

在 C# 3.0 中,我们可以使用新的查询表达式语法,写有关映射和筛选数据的操作。查询表达式还支持许多其他操作,但我们会只关注映射和筛选,来演示函数技术和 F# 功能。

F# 虽然没有专门提供的查询表达式,但是,使用序列表达式,仍可以轻松地写出映射和筛选数据的查询。这是因为序列表达式在 F# 中所有地方都可以使用,而不仅仅是返回序列的函数。清单 12.9 显示了使用 C# 中的查询和 F# 中的序列表达式,实现我们前面的示例。

 

清单 12.9 在 C# 和 F# 中的筛选和映射序列

C#

F#

var nums1 =

  from n in nums

  where n%3 == 0

  select n * n;

let nums1 = seq {

  for n in nums do

    if (n%3 = 0) then

      yield n * n }

 

在 C# 中,查询表达式和迭代器是完全不同的,而在 F# 中,序列表达式表明,它们在概念上是相关的。查询表达式中的每个部分在 F# 中都有对应的结构,而且总是更加一般:from 子句由简单的 for 循环取代,where 子句由 if 条件取代,select 子句与有映射的 yield 语句相对应,表示为通常的计算。

C# 查询表达式语法还有另外一些运算符,用 F#序列表达式不容易表达。因此,C# 版本功能更强大,而 F# 的实现更加统一。

要注意一下C# 查询表达式和 F# 序列表达式内部的运行。C# 查询表达式使用 lambda 表达式,以明确的定义转化成一系列调用,比如:Where、Select、SelectMany、Join 和 GroupBy。这些通常是扩展方法,但也不一定,编译器不关心查询表达式的意思,只要翻译的代码是有效的就行。这个“数据源不可知论(datasource agnosticism)”对于数据处理的方法,比如LINQ to Objects 和 LINQ to SQL,至关重要,我们不久将使用它,展示查询语法如何用来处理其它种类的值。

另一方面,序列表达式能够表达更加复杂和多方面的结构。我们可以复制 yield 结构,把数据源中的一个项目返回为两个元素。这个使用 C# 中的迭代器可以很容易实现,但是,使用内嵌的查询语法,表示这种转换,是不可能的。

 

LINQ 中的其他查询运算符

 

在 C# 3.0 中,查询表达式语法是专为从各种数据源查询和格式化数据的,因此,它的操作不止映射和筛选。这些运算符主要就为此目的,在 F# 中没有专门对应的语法。所有这些标准运算符都可以用操作序列的常规高阶函数来实现。例如,排序数据:

var q =

  from c in customers

  orderby c.Name

  select c;

[

合理的话,这里也应该是 C.City

]

let q =

  customers

  |> Seq.sortBy (fun c -> c.City)

作为给 Seq.sortBy 运算符的第一个参数的函数,指定在比较两个元素时,应该处理元素的哪个属性。在 C# 的查询语法中,对应于跟在  orderby 子句后的表达式;C# 编译器使用 lambda 函数,将此表达式转换为对标准OrderBy 方法的调用。F# 中唯一查用的操作,是作为高阶函数的分组:

var q =

  from c in customers

  group c by c.City;

let q =

  customers

  |> Seq.groupBy (fun c -> c.City)

对序列进行分组,需要指定返回键的函数,键表示元素所属的组。C# 还是有专门的语法,而在 F# 的代码段中,我们使用标准的 lambda 函数。

在这些示例中,两个版本的代码看起来是合理的。然而,当我们写 F# 的代码,需要操作把只能使用高阶函数的映射和筛选混到一起,那么,等效的 C# 查询表达式会更容易理解。

 

在 F# 编译器中,序列表达式的实现进行了优化,但是,如果没有这些优化,它可能与 C# 查询表达式一样运行。任可序列表达式,都可以转化为标准的函数调用序列。类似于 C#,我们可以提供这些函数的自定义实现,这样,就可以更深入理解 F# 中转换是如何运行的。F# 语言使用数量很少的操作,严重依赖于一个操作,称为平面映射(flattening projection)。

12.3.2.2 使用查询和序列表达式

标签:f#   函数编程   实用函数编程   序列表达式   查询表达式   

原文地址:http://blog.csdn.net/hadstj/article/details/43062071

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!