Преобразование функции JavaScript с помощью Clojure - PullRequest
0 голосов
/ 24 августа 2018

Я новичок в мире 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? У меня уже есть код, использующий макрос Clojure «cond», но я не уверен насчет неизменяемой строки «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 голосов
/ 24 августа 2018

Если у вас есть только несколько проверок «равного числа», я бы просто пошел с картой. Э.Г.

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

Я думаю, что ключевым моментом здесь является устранение дублирования; не только исключить «длину», но и устранить «ширину» вашего кода.

0 голосов
/ 26 августа 2018

Ваша 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, за которыми вам нужно следить, а язык затрудняет это в первую очередь.Если вы видите простую функцию, использующую стандартные операторы, очень маловероятно, что она делает что-то небезопасное.

0 голосов
/ 24 августа 2018

Требуется макрос 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"

Обязательно посмотрите

...