此代码似乎将对象视为一组键值对:
for (var a in b) { ...
我想把它映射到ClojureScript
现在通常我可以这样做:
(doseq [[k v] (js->clj js/b)]
问题是b
包含嵌套地图 - js-clj
很浅。
另一个问题是对象中的键是整数 - 因此按字段值访问键将不起作用。即
{0 #object... 1 #object ... }
我的问题是:如何将JavaScripts for (var a in b)
深度映射到ClojureScript?
答案 0 :(得分:0)
(doc js->clj)
-------------------------
cljs.core/js->clj
([x] [x & opts])
Recursively transforms JavaScript arrays into ClojureScript
vectors, and JavaScript objects into ClojureScript maps. With
option ':keywordize-keys true' will convert object fields from
strings to keywords.
正如您所见js-clj
将JS对象递归转换为ClojureScript数据结构。
所以当你有一个JS对象时:
{1: {2: "a"}, 3: [true, 4]}
js->clj
会将其转换为以下ClojureScript对象:
{"1" {"2" "a"}, "3" [true 4]}
据我所知,当您使用for
迭代JS对象属性时,它将仅迭代您传递的对象的属性,而不会进入这些属性'属性:
for (a in {1: {2: "a"}, 3: {4: "b"}) { console.log(a); };
它只打印1
和3
,不会进入2
或4
。
因此for
循环的ClojureScript版本将是:
(doseq [[k v] (js->clj js/g)]
(.log js/console k))
所以我不清楚为什么你说js->clj
在它不是时很浅。
如果您想以递归方式遍历整个数据结构,那么您可以使用clojure.walk/prewalk
或clojure.walk/postwolk
来访问数据结构中的所有值(它知道如何进入地图,向量,设置等)并为遇到的每个值调用函数:
(clojure.walk/postwalk
#(do (.log js/console "PostWalking" %)
%)
{:a 1 :b {:c 2}})
(clojure.walk/prewalk
#(do (.log js/console "PreWalking" %)
%)
{:a 1 :b {:c 2}})