0

我正在调用一个 Javascript 库并返回一个 Map Iterator(在 Javascript 中您使用 for ... in)

如何将其转换为 ClojureScript 序列以便调用for它?

4

1 回答 1

1

通过查看关于 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" }

如果你想要一个键值对序列,你可以使用相同的原理来创建一个惰性序列,你只需要记住持有对迭代器的引用,这样你就可以提取下一个项目。

于 2020-08-11T04:20:02.220 回答