如何在Clojure中迭代一系列数字?

时间:2014-12-30 16:20:55

标签: clojure

我为我的朋友写了一个简单的python函数来说明为什么一个数字现在是一个素数:

def why_not_prime(n):
    if n==2:
        print(n, "is a prime.")
    for i in range(2,n):
        if n%i == 0:
            print(n, "is not a prime because it could be divided by", i,".")
            break
        else:
            print(n, "is a prime.")
            break

我尝试将其转换为Clojure,但我无法找到方法。我不知道如何处理for i in range(2,n)。通常的做法是什么?

1 个答案:

答案 0 :(得分:2)

在Clojure中,实际上没有通用答案,因为它是由为什么要迭代这些数字决定的。
您可能希望为每个数字生成一些值,然后在列表中收集它们,在这种情况下,您要使用mapfor。您可能希望以某种方式“汇总”它们(例如将它们全部加在一起),在这种情况下,您希望使用类似reduce的内容。
在这种情况下,您需要一种特殊的摘要;你想知道在“适当”的范围内是否有某个值(在这种情况下是n的除数)。这种用例称为some有一个核心函数,但它需要一个函数来告诉它什么是“适当的”值。没有基本功能可以完成我们想要的任务,但我们可以创建一个。

(defn why-not-prime [n]
  (let[checker (fn [divisor] ;; A local function under the name checker, with one argument
                 (if (= 0 (mod n divisor));; If that argument is a divisor of n
                   divisor ;;then return it
                   false)) ;; otherwise return false - this value wasn't "appropriate"
       witness (some checker (range 2 n))] ;; witness will be the first value that satisfies checker
              ;if there isn't such a value, witness is nil
    (if witness
      (str n " is composite because it can be divided by " witness)
      (str n " is prime."))))

现在,这会稍微重新解决您的问题,因为它不会打印任何消息,但只有返回包含一个消息的字符串。这是一种功能性语言中更惯用的表述,您通常会尽可能地推迟打印等副作用。如果要打印,可以使用println包裹整个函数体。