Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 如何使用specter合并两个不同的集合?_Clojure_Clojurescript_Specter - Fatal编程技术网

Clojure 如何使用specter合并两个不同的集合?

Clojure 如何使用specter合并两个不同的集合?,clojure,clojurescript,specter,Clojure,Clojurescript,Specter,我正在尝试编写一个合并方法来动态生成CSS样式。此方法应采用断点、和样式参数,并创建一个映射,我们使用stylefy进行样式设置 我尝试使用specter来实现这一点,但无法获得预期的结果 我一直尝试的代码如下: (defn merge-style [breakpoints style] (let [media-queries (s/transform [s/ALL] #(hash-map :min-width (str %1 "px")) breakpoints)] breakpo

我正在尝试编写一个合并方法来动态生成CSS样式。此方法应采用
断点、
样式
参数,并创建一个映射,我们使用stylefy进行样式设置

我尝试使用specter来实现这一点,但无法获得预期的结果

我一直尝试的代码如下:

(defn merge-style
  [breakpoints style]
  (let [media-queries (s/transform [s/ALL] #(hash-map :min-width (str %1 "px")) breakpoints)]
  breakpoints))
该方法的工作原理如下:

(def breakpoints ["320px" "600px" "1280px"])
(def style {:padding-top ["20px" "30px" "40px" "50px"]
            :margin "30px"
           })

(merge-style breakpoints style)
输出应如下所示:

{:padding-top "20px"
 :margin "30px"
 ::stylefy/media {{:min-width "320px"} {:padding-top "30px"}
                  {:min-width "600px"} {:padding-top "40px"}
                  {:min-width "1280px"} {:padding-top "50px"}}
 }
解决方案: 我用下面的函数为自己解决了这个问题

(defn- get-media-queries
  [breakpoints styles]
  (let [base-style (s/transform [s/MAP-VALS] #(%1 0) styles)
        styles-maps (s/setval [s/MAP-VALS empty?] s/NONE (s/setval [s/MAP-VALS s/FIRST] s/NONE styles))
        styles-list (map (fn [[key val]] (map #(hash-map key %1) val)) styles-maps)
        styles-final (apply vdu/merge-maps styles-list)
        breaks (map #(hash-map :min-width %1) breakpoints)
        styles-merged (into {} (mapv vector breaks styles-final))
        ]
    (assoc base-style ::stylefy/media styles-merged)))

非常感谢您提供的帮助。

在这一点上不需要幽灵。只需使用基本Clojure:

(ns tst.demo.core
  (:use demo.core tupelo.core tupelo.test) )

(def desired
  {:padding-top   "20px"
   :margin        "30px"
   :stylefy/media {{:min-width "320px"}  {:padding-top "30px"}
                   {:min-width "600px"}  {:padding-top "40px"}
                   {:min-width "1280px"} {:padding-top "50px"}}})

(def breakpoints [320 600 1280])
(def padding-top ["30px" "40px" "50px"])
(def base {:padding-top "20px"
           :margin      "30px"})

(dotest
  (let [mw     (for [it breakpoints]
                 {:min-width (str it "px")})
        pt     (for [it padding-top]
                 {:padding-top it})
        pairs  (zipmap mw pt)
        result (assoc base :stylefy/media pairs)]
    (is= desired result)))
注意,因为我没有
stylefy
的名称空间别名,所以我只使用关键字的单冒号版本


更新2019-9-12
我刚刚重温了这篇文章,注意到我本应该使用
zipmap
而不是
zip
,即使之前的版本(意外地!)得到了正确的答案。

请添加您尝试过的内容以及失败的原因,以便我们可以改进。@cfrick我已经更新了到目前为止我编写的代码。由于我是clojure的初学者,我发现很难思考如何以功能的方式解决问题。我也发现了同样的问题。Specter不适合从现有数据结构生成新的数据结构。非常感谢你的帮助。