【问题标题】:Converting a javascript function using Clojure使用 Clojure 转换 javascript 函数
【发布时间】:2018-08-24 19:22:38
【问题描述】:

我是 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"))))

【问题讨论】:

  • 请添加你已经尝试过的cljs代码。

标签: clojure clojurescript


【解决方案1】:

你想要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"

一定要看

【讨论】:

  • cond-> 在您想有条件地逐个子句地线程化时很有用。问题是只选择一个子句。
【解决方案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 中修改您需要留意的东西并不是一个错误,而是该语言从一开始就很难做到这一点。如果您看到一个使用标准运算符的简单函数,那么它不太可能做一些不安全的事情。

【讨论】:

    【解决方案3】:

    如果您只有一些“等号”支票,我会选择地图。例如

    (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")
    

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

    【讨论】:

      猜你喜欢
      • 2019-10-14
      • 1970-01-01
      • 1970-01-01
      • 2020-11-22
      • 1970-01-01
      • 2019-11-23
      • 1970-01-01
      • 1970-01-01
      • 2016-06-02
      相关资源
      最近更新 更多