我正在调用一个 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" }
如果你想要一个键值对序列,你可以使用相同的原理来创建一个惰性序列,你只需要记住持有对迭代器的引用,这样你就可以提取下一个项目。