使用Clojure转换javascript函数

时间:2018-08-24 19:22:38

标签: clojure clojurescript

我在Lisp / Functional / Clojure世界中很新,并且具有JS函数:

function buildString(someInteger) {

   var question = "Initial text";

   if (someInteger == 1) {
     question += " put this string ";
   } else if(someInteger == 2) {
     question +=  " oh! another string ";
   } else if(someInteger == 3) {
     question +=  " guess what? ";
   }
   return question;
  }

将其重写为Clojure函数的最佳方法是什么?我已经有一些使用“ cond” Clojure宏的代码,但是我不确定不变的字符串“ question”:

(defn build-string [some-integer]
  (let [question "Initial text"]
    (cond
      (= some-integer 1) (str question "Add string one")
      (= some-integer 2) (str question "Add string two")
      (= some-integer 3) (str question "Add string three"))))

3 个答案:

答案 0 :(得分:2)

您想要cond->宏:

(defn build-string [some-integer]
  (let [question "Initial text; "]
    (cond-> question
      (= some-integer 1) (str "Add string one")
      (= some-integer 2) (str "Add string two")
      (= some-integer 3) (str "Add string three"))))

(build-string 1) => "Initial text; Add string one"
(build-string 2) => "Initial text; Add string two"
(build-string 3) => "Initial text; Add string three"

尽管在这种情况下,普通的旧cond也可以使用:

(defn build-string [some-integer]
  (let [question "Initial text; "]
    (cond
      (= some-integer 1) (str question "Add string one")
      (= some-integer 2) (str question "Add string two")
      (= some-integer 3) (str question "Add string three"))))

@cfrick指出了一个重点:

(defn build-string-map [some-integer]
  (let [question "Initial text; "
        data     {1 "Add string one"
                  2 "Add string two"
                  3 "Add string three"}
        suffix   (get data some-integer)
        result   (str question suffix)]
    result))


(build-string-map 1) => "Initial text; Add string one"
(build-string-map 2) => "Initial text; Add string two"
(build-string-map 3) => "Initial text; Add string three"

请务必查看

答案 1 :(得分:2)

您的cond格式很好,但是您可以在此处使用case

(defn build-string [some-integer]
  (str "Initial text"
       (case some-integer
         1 "Add string one"
         2 "Add string two"
         3 "Add string three")))

您的“不可变字符串问题”:与您的JavaScript版本相反,您或我一直未使用的运算符修改其任何参数。例如,Clojure的str构建了一个新字符串,而JavaScript的+=修改了一个变量。您不必担心:修改Clojure中您需要引起注意的内容并不是错误,但是从一开始,这种语言就很难做到这一点。如果您看到使用标准运算符的简单函数,那么就很难做一些不安全的事情。

答案 2 :(得分:1)

如果您只进行一些“等号”检查,那我就去看看地图。例如

(str "Initial text" ({1 "Add string one" 2 "Add string two" 3 "Add string three"} some-integer))

或者直接使用condp。例如

(defn build-string  
  [some-integer]
  (str "Initial text"
       (condp = some-integer
         1 "Add string one"
         2 "Add string two"
         3 "Add string three"
         nil)))

(map build-string (range 4))
; => ("Initial text" "Initial textAdd string one" "Initial textAdd string two" "Initial textAdd string three")

我认为这里的重点是消除重复;不仅消除了代码的“长度”,而且消除了代码的“宽度”。