我希望能够遍历集合,但是使用该循环维护计数器。我设法创造了例如。
(for [[email i] (map vector emails (range))]
...)
要做到这一点,但理想情况下,我更喜欢fori
宏(除非功能可行,但我的直觉说它必须是一个宏)才能让我做同等的事情
(fori [email i emails]
...)
或
(fori [[email i] emails]
...)
我没有使用宏的经验,并且查看for
宏的来源,看起来非常令人生畏。有什么帮助吗?
Super-cool将是一个遵循for
语法并允许例如
(fori [email i emails
line j (lines email)]
...)
答案 0 :(得分:2)
您可以编写一个扩展为for
的宏,但我并不是真的相信它有多重要。正是出于这个目的,有许多内置函数,fori
语法并不能很好地读取。至少看起来应该是
(fori [[email i] emails,
[line j] (lines email)]
...)
但如果你真的想按照你说的那样写出来,那肯定不是不可能的:
(defmacro fori [bindings body]
(letfn [(clauses [bindings]
(lazy-seq
(cond (empty? bindings) ()
(keyword? (first bindings)) (concat (take 2 bindings)
(clauses (drop 2 bindings)))
:else (let [[name index value] (take 3 bindings)]
(list* [index name] `(map-indexed vector ~value)
(clauses (drop 3 bindings)))))))]
`(for [~@(clauses bindings)]
~body)))
user> (macroexpand-1 '(fori [email i xs,
:when (even? i)
line j (lines email)]
[i line]))
(for [[i email] (map-indexed vector xs)
:when (even? i)
[j line] (map-indexed vector (lines email))]
[i line])
答案 1 :(得分:0)
(defn fori [coll]
(map-indexed (fn [idx itm] [idx itm]) coll))
可能是你想要的。 e.g。
(fori [:a :b :c :d])
产生
([0 :a] [1 :b] [2 :c] [3 :d])
顺便说一句,因为它不是循环,而是创建列表理解。如果你想在循环中做一些副作用,你应该考虑剂量。