转换此表单的列表:
( arg1 arg2 ... :first_keyword val_1 :key2 val_2 ... )
进入此地图:
{ 1 arg1, 2 arg2, ..., :first_keyword val_1, :key2 val_2, ... }
我可以看到非常丑陋的方式来做到这一点。但Clojure的做法是什么?
.
.
.
(P.S。我对Clojure的早期反应是它感觉有点像 优化了更多"玩具般的"任务。如果逻辑连接您的输入 和输出有任何头发,然后我觉得我花了更多 努力打击语言而不是问题。特别, 跟踪你的复发中的第五个参数'声明感觉 就像我正在做一些编译器应该做的事情...... 但也许我的Clojure愿景仍然太弱......)
答案 0 :(得分:4)
这是一个解决方案:
(let [[vals keyvals]
(split-with (complement keyword?)
[100 101 102 :a 103 :b 104 :c 105])]
(merge (zipmap (range) vals)
(apply hash-map keyvals)))
=> {:a 103, :b 104, :c 105, 2 102, 1 101, 0 100}
这使得0成为第一个元素的关键。如果您想要基于1的密钥,可以将(range)
包裹在(map inc _)
。
其他说明:
(split-with (complement keyword?) ...)
将序列分为两部分:一个没有关键字的序列,其余部分。
(zipmap (range) vals)
将两个序列“拉”成一张地图,使用range
中与vals
一样多的整数。
答案 1 :(得分:1)
(loop [inputs ["arg1" "arg2" :key1 1 :key2 2] index 1 output {}]
(if (empty? inputs) output
(let [input (first inputs) rest-inputs (rest inputs)]
(if (keyword? input)
(recur (rest rest-inputs) index (assoc output input (second inputs)))
(recur rest-inputs (inc index) (assoc output index input))))))
您可以使用for
理解或reduce
进行一些预处理,但在这种情况下循环可能最干净。