13.4.3 收集有关地区的统计信息
我们的目标是,自 1990 年以来不同地区森林面积的变化。我们需要遍历所有地区,测试数据是否可用,并找到下载的指标值。这可以使用创建的映射非常轻松地完成,因为有年份和地区 ID 作为键值。
我们必须小心,因为一些数据可能会省略,所以,我们要过滤掉没有数据我们感兴趣的所有年份的任何地区。还想要显示森林的总面积,而不是百分比,所以,在返回数据之前,需要一个简单的计算。虽然这听起来可能很难,但是,代码并不非常复杂。清单 13.17 显示,最终,我们只需要在 F# Interactive 中,输入几条命令,就能得到我们想要收集的数据。
Listing 13.17 Calculating information about forested area (F# Interactive)
> let calculateForests(area:float<km^2>, forest:float<percent>) =
let forestArea = forest * area
forestArea / 100.0<percent>
;;
val calculateForests : float<km ^ 2> * float<percent> -> float<km ^ 2>
> let years = [ 1990; 2000; 2005 ]
let dataAvailable(key) =
years |> Seq.forall (fun y –>
(Map.contains (y, key) areas) &&
(Map.contains (y, key) forests));;
val years : int list
val dataAvailable : string –> bool
> let getForestData(key) =
[| for y in years do
yield calculateForests(areas.[y, key], forests.[y, key]) |];;
val getForestData : string -> float<km ^ 2> array
> let stats = seq {
for name in regions do
if dataAvailable(name) then
yield name, getForestData(name) };;
val stats : seq<string * float<km ^ 2> array>
清单 13.17 定义了几个辅助函数,处理下载的数据,并定义了一个名为 stats(统计数据)的值,包含最后结果。由于有了度量单位,可以轻松看到,第一个函数做了什么,它的计算森林总占地面积,以平方公里计,用该地区的总面积和森林面积的百分比。
第二个函数测试我们所需要的数据,对于指定的地区 ID,和我们感兴趣的三年是否可用。它使用函数 Map.contains,测试 F# 映射 (指定为第二个参数值)是否包含作为第一个参数值的键值。最后一个工具函数看起来和第二个相似。它假定数据可用,并从映射中提取数据,使用年以及地区名作为键值,所有监控的年份。然后,使用的第一个函数,从原始数据计算森林面积。
有了最后两个函数,我们可以收集所有地区的统计数字。返回值是一个元组的序列,包含了地区名作为第一个元素,数组为第二个元素。数组具有三个元素,对应于我们监控的三年的值。
在 F# Interactive 中获取数据以后,就可以观察一下,但是,很难看到通过在互动窗口中,输出数据的任何模式。要从收集的数据中获取最大,要以更便于用户使用的方式,对它们进行可视化,例如,使用 Microsoft Excel。