现在,消除了换行之后,我们需要进行到整数的转换。浏览清单 12,会注意到我们使用了 map 函数,它接受两个参数:一个函数和一个序列。它返回一个新的序列,该序列的第 n 个元素是将此函数应用到原始序列的第 n 个元素后的结果。对于这个函数,我们再次使用了一个简短的闭包注释。首先,我们使用 Clojure 的 str 函数来将这个 char 转变为字符串。我们为什么要这么做呢?因为,接下来,我们要使用 java.lang.Integer 的构造函数来创建一个整数。而这是由 Integer 注释的。应该将这个表达式视为新的 java.lang.Integer(str(%))。联合使用它与 map 函数,我们就能如愿地得到一个整数序列。现在,我们来解决这个问题。
清单 14. 示例 3(println (apply max (map #(reduce * %) (for [idx (range (count the-digits))] (take 5 (drop idx the-digits))))))
要理解这段代码的含义,让我们从 for 宏开始。它不同于 Java 语言中的 for 循环,它是一个序列推导式。首先,我们使用一些方括号来创建一个绑定。在本例中,我们将变量 idx 绑定到一个从 0 到 N-1 的序列,其中 N 是序列 the-digits 中的元素的数量(N = 1,000,因为原始的数值具有 1,000 位)。接下来,for 宏获取一个表达式来生成一个新的序列。它将迭代 idx 序列中的每个元素,求得表达式的值,并将结果添加到这个返回序列。不难看出,这在某些方面充当了 for 循环的功能。在此推导式中所使用的表达式首先使用 drop 函数来向下移(drop)此序列的第一个 M 元素,然后使用 take 函数来取得此截短序列的前五个元素。M 将是 0,然后是 1,2,以此类推,所以结果将是一个包含序列的序列,其中的前五个元素将是 (e1, e2, e3, e4, e5),下一个元素将是 (e2, e3, e4, e5, e6),以此类推,其中的 e1、e2 等均是来自 the-digits 的元素。
有了这个包含序列的序列之后,我们就可以使用 map 函数了。我们使用 reduce 函数将五个数组成的每个序列转换成这五个数的乘积。现在,我们就得到了一个整数序列,其中的第一个元素是元素 1-5 的乘积,第二个元素是元素 2-6 的乘积,以此类推。我们想要得到最大的乘积。为此,我们使用 max 函数。然而,max 一般接受传递给它的多个元素,而不是单一一个序列。为了将这个序列转变为多个元素后再传递给 max,我们使用 apply 函数。这会产生我们想要的最大数,当然还会打印出结果。现在,您已经解决了几个问题,并同时掌握了该如何使用 Clojure。
结束语在本文中,我们介绍了 Clojure 编程语言并从 Eclipse 的 Clojure 插件的使用中受益匪浅。我们先是简单查看了其原理和特性,之后重点介绍了几个代码示例。在这些代码示例中,我们逐渐了解了该语言的核心特性:函数、宏、绑定、递归、惰性序列、闭包、推导式以及与 Java 技术的集成。Clojure 还有很多其他的方面。我希望,该语言已经吸引了您,以至于您有兴趣借助本文所列的一些参考资料来深入了解它。