#clojure #clojurescript
#clojure #clojurescript
Вопрос:
Я довольно новичок в языках Clojurescript и LISPy, поэтому, пожалуйста, извините мой императивный образ мышления.
Я использую Raphael.js чтобы нарисовать некоторые вещи. Это позволяет вам определить набор, поместить в него объекты (скажем, круг, прямоугольник и контур), а затем выполнить операцию, которая воздействует на все элементы (пример: поворот, который применяется ко всем).
Таким образом, мы можем иметь (где paper
— это в основном элемент svg):
(-> (.set paper)
(.push (.ellipse paper 10 10 10 10))
(.push (.circle paper 10 10 10 10))
(.transform (format "r%.2f" 180)))
Который создаст набор и будет использовать несколько вызовов к push
, который возвращает набор каждый раз, в конечном итоге вызывая transform
. Теперь, что, если я хочу создать список, скажем, circle
объектов во время выполнения и добавить их в набор? В идеале я хотел бы иметь возможность заменить, скажем, строку 3 приведенного выше блока кода чем-то вроде (очень грубо — я совершенно не уверен в том, как обращаться с .push
)
(.push (map (fn [i] (.ellipse paper 10 (* i 10) 10 10)) (range 5)))
для того, чтобы создать 5 кругов, спускающихся по оси y. Чего я не могу понять с моим ограниченным пониманием Clojure, так это как сделать такую вещь довольно простым способом, не прибегая к doseq
чему-либо еще. Я не хочу побочных эффектов. Я хотел бы каким-то образом создать список нажатий, а затем заставить их все объединиться в мой блок на месте. Возможно ли это? Где-то в моем мышлении может быть огромный недостаток, и я был бы действительно очень благодарен любому, кто может указать на это.
Большое спасибо.
Ответ №1:
Избежать побочных эффектов немного сложно, поскольку push
очевидно, что это приводит к изменению набора. Один из способов избежать doseq
— использовать reduce
. Например:
(def shapes [ (.circle paper 10 10 10 10) (.ellipse paper 10 10 10 10) ] )
(defn push-all [set shapes]
(reduce #(.push %1 %2) set shapes))
(-> (.set paper)
(push-all shapes)
(.transform (format "r%.2f" 180)))
Комментарии:
1. Большое вам спасибо. Я пытался использовать
reduce
для выполнения этого в какой-то момент. Я немного ошибся, сказав, что хотел избежать побочных эффектов, поскольку вы правы, сказав, что.push
это в любом случае изменяет состояние. К сожалению, у меня недостаточно репутации, чтобы поддержать вас, поэтому вместо этого я посылаю вам немного реальной кармы.