简体   繁体   English

ClojureScript 将一个 Javascript Map Iterator 变成一个 seq

[英]ClojureScript turn a Javascript Map Iterator into a seq

I'm calling a Javascript library and getting a Map Iterator back (which in Javascript you use with for... in)我正在调用 Javascript 库并返回 Map 迭代器(在 Javascript 中用于...

How do I turn this into a ClojureScript sequence so I can call for on it?如何将其转换为 ClojureScript 序列, for我可以调用它?

By looking at the MDN documentation on Map iterator you can check that you can navigate the iterator with the .next() method which will return a JS object with 2 properties: value and done , where value will contain an Array of size 2 with the key and value for each entry on the Map, and done , which will be false until the iterator is exhausted (no more entries).通过查看关于 Map 迭代器的 MDN 文档,您可以检查是否可以使用.next()方法导航迭代器,该方法将返回具有 2 个属性的 JS object: valuedone ,其中value将包含一个大小为 2 的数组,其中Map 上的每个条目的键和值,并且done ,在迭代器耗尽(不再有条目)之前,这将是错误的。

Using this, we can create a ClojureScript function that takes the iterator and builds a Map (or a ClojureScript map if you remove the clj->js ).使用它,我们可以创建一个 ClojureScript function,它采用迭代器并构建一个 Map(或者如果删除 clj,则为 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)))))))

I used the ^:export metadata flag so that you can call the function from the console.我使用了^:export元数据标志,以便您可以从控制台调用 function。 If you save this function in say app/main.cljs , the function will be available as app.main.iterToMap() in the global JS object.如果将此 function 保存在app/main.cljs中,则 function 将在全局 JS ZA8CFDE6331BD59EB2AC96F8911C4B66 中以app.main.iterToMap()的形式提供

You can use it as follows in the Developer Console:您可以在开发者控制台中按如下方式使用它:

> 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" }

If you want a sequence of key-value pairs, you can use the same principle to create a lazy-sequence , you just need to remember to hold a reference to the iterator so you can extract the next item.如果你想要一个键值对序列,你可以使用相同的原理来创建一个惰性序列,你只需要记住持有对迭代器的引用,这样你就可以提取下一个项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM