dav*_*gan 21 enumeration clojure
在Python中我可以这样做:
animals = ['dog', 'cat', 'bird']
for i, animal in enumerate(animals):
print i, animal
Run Code Online (Sandbox Code Playgroud)
哪个输出:
0 dog
1 cat
2 bird
Run Code Online (Sandbox Code Playgroud)
我如何在Clojure中完成同样的事情?我考虑使用这样的列表理解:
(println
(let [animals ["dog" "cat" "bird"]]
(for [i (range (count animals))
animal animals]
(format "%d %d\n" i animal))))
Run Code Online (Sandbox Code Playgroud)
但这会打印出数字和动物的每一个组合.我猜有一种简单而优雅的方法可以做到这一点,但我没有看到它.
kot*_*rak 36
map-indexed1.2中有核心.
你的例子是:
(doseq [[i animal] (map-indexed vector ["dog" "cat" "bird"])]
(println i animal))
Run Code Online (Sandbox Code Playgroud)
快速解决方案
(let [animals ["dog", "cat", "bird"]]
(map vector (range) animals))
Run Code Online (Sandbox Code Playgroud)
或者,如果要将其包装在函数中:
(defn enum [s]
(map vector (range) s))
(doseq [[i animal] (enum ["dog", "cat", "bird"])]
(println i animal))
Run Code Online (Sandbox Code Playgroud)
这里发生的是函数向量应用于两个序列中的每个元素,结果收集在一个惰性集合中.
来吧,在你的repl中尝试一下.
使用从clojure.contrib.seq索引:
用法:(indexed s)
返回[index,item]对的延迟序列,其中项目来自's',索引从零开始计数.
(indexed '(a b c d)) => ([0 a] [1 b] [2 c] [3 d]
对于你的例子,这是
(require 'clojure.contrib.seq)
(doseq [[i animal] (clojure.contrib.seq/indexed ["dog", "cat", "bird"])]
(println i animal))
Run Code Online (Sandbox Code Playgroud)
map-indexed看起来不错,但是:doseq在其他答案中,我们真的需要所有的和解构的args吗?
(map-indexed println ["dog", "cat", "bird"])
Run Code Online (Sandbox Code Playgroud)
编辑:
正如@gits指出的那样,这在REPL中有效,但默认情况下不尊重clojure是惰性的。dorun似乎是最接近之中doseq,doall而doseq这一点。doseq,不过,似乎是这里的惯用法。
(dorun (map-indexed println ["dog", "cat", "bird"]))
Run Code Online (Sandbox Code Playgroud)