我正在调用一个 Javascript 库并返回一个 Map Iterator(在 Javascript 中您使用 for ... in)
如何将其转换为 ClojureScript 序列以便调用for
它?
我正在调用一个 Javascript 库并返回一个 Map Iterator(在 Javascript 中您使用 for ... in)
如何将其转换为 ClojureScript 序列以便调用for
它?
通过查看关于 Map iterator 的 MDN 文档,您可以检查是否可以使用该方法导航迭代器,该.next()
方法将返回具有 2 个属性的 JS 对象:value
并且done
,其中value
将包含一个大小为 2 的数组,其中每个条目的键和值Map 和done
,在迭代器用尽(不再有条目)之前,这将是错误的。
使用它,我们可以创建一个 ClojureScript 函数,该函数接受迭代器并构建一个 Map (如果删除 ,则为 ClojureScript 映射clj->js
)。
(defn ^:export iterToMap [iter]
(loop [acc {}]
(let [elem (.next iter)]
(if (.-done elem) ;; no more elements
(clj->js acc) ;; or just use `acc` for a regular CLJS map
(let [[k v] (array-seq (.-value elem))]
(recur (assoc acc k v)))))))
我使用了^:export
元数据标志,以便您可以从控制台调用该函数。如果将此函数保存在 say 中app/main.cljs
,则该函数将app.main.iterToMap()
在全局 JS 对象中可用。
您可以在开发者控制台中按如下方式使用它:
> const map1 = new Map();
> map1.set("0", "zero");
> map1.set("1", "one");
// Now call the function, note that map1.entries() returns an Iterator:
> app.main.iterToMap(map1.entries());
// Returns:
Object { 0: "zero", 1: "one" }
如果你想要一个键值对序列,你可以使用相同的原理来创建一个惰性序列,你只需要记住持有对迭代器的引用,这样你就可以提取下一个项目。