12.3.3.1 序列表达式中的平面映射

来源:互联网 发布:淘宝怎么发帖 编辑:程序博客网 时间:2024/04/28 00:11

12.3.3.1 序列表达式中的平面映射

 

假设我们有一个关于城市的元组列表,每个元组包含城市的名字和它所在的国家,另外,我们还有一个列表,是用户所选的城市。因此,我们可以这样表示样本数据:

 

let cities = [ ("New York","USA"); ("London", "UK");

                  ("Cambridge","UK"); ("Cambridge", "USA") ]

let entered = [ "London";"Cambridge" ]

 

现在,假设我们要找出选定城市的国家。我们可以在 cities 列表中遍历所选的城市,找到国家。你可能可能已经看出了这种方法的问题了:有一个名为 Cambridge 的城市,在英国和美国都有,因此,对于一个城市,需要能够返回多条记录。在清单 12.10 中可以看到,我们在序列表达式中使用两个嵌套的 for 循环。

 

清单12.10 使用序列表达式联接集合 (F# Interactive)

> seq { for name in entered do     [1]

              for (n, c) in cities do     [2]

                if (n = name) then            | [3]

                  yield sprintf "%s(%s)" n c };;  |

val it : seq<string> =                                   | 返回剑桥的

seq [ "London (UK)";"Cambridge (UK)"; "Cambridge (USA)" ]  | 两个国家

 

外层的 for 循环遍历 entered 中的名字[1],嵌套的循环遍历 cities 列表[2]。这样,在嵌套的循环体内部,我们就可以比较每个输入城市的名字,是否与每个已知城市的名字相等。如果名字相同的话,嵌套在两个循环内的代码[3]使用 yield 语句,生成一个项目;如果名字不一样,就不产生任何元素。

用数据库术语来说,这个操作可以用联接(jion)来解释。输入名字的列表与包含城市信息的列表,使用城市名字作为键,进行联接。使用序列表达式来写这个代码是很容易的,它是 F# 中联接编程的首选方式。

我们提到过,任何序列表达式可以写成使用平面映射的操作,因此,我们可以看一下如何显式使用 Seq.collect 重写前面的示例。实际你不会这样做,但是,当我们研究类似于可选工作流,定义自己的、序列表达式时,这将是非常宝贵的。

0 0
原创粉丝点击