6

我想迭代一个集合,同时还维护一个计数器 ex

(for [x (range 10) y (inc 0)] [x y] )

我希望'y'代表计数器,因此对于每个元素,输出都是([0 0] [1 1] [2 2] ...)。我怎么做?

4

5 回答 5

12

您可以使用indexed来自clojure.contrib.seq. 例子:

(indexed '(a b c d))  =>  ([0 a] [1 b] [2 c] [3 d])

您也可以使用map-indexed. 例子:

(map-indexed vector "foobar")  =>  ([0 \f] [1 \o] [2 \o] [3 \b] [4 \a] [5 \r])
于 2012-06-19T13:04:57.240 回答
6

按照 Simeon 的建议使用map-indexed。在for上下文中,使用解构来轻松访问计数器和集合元素很方便:

(for [ [y x] (map-indexed vector (range 10) ) ] [x y] )

> ([0 0] [1 1] [2 2] [3 3] [4 4] [5 5] [6 6] [7 7] [8 8] [9 9])
于 2012-06-19T13:52:54.470 回答
2

我想如果这个问题仍然没有被标记为“已回答”,那么您可能正在寻找其他东西,也许是定义您自己的计数器的灵活性。

我同意其他人的观点,对于您概述的特定问题,这map-indexed是可行的方法。但是,如果您坚持使用for,我会推荐这样的东西:

(for [[x y] (map vector (range 10) (iterate inc 0))]
  [x y])

Rafal 有一个非常相似的答案,除了计数器总是从零开始并以 1 递增。在我的版本中,您可以根据需要定义您的计数器。例如,通过将上面的内容更改(iterate inc 0)(iterate #(+ 2 %) 10),您可以改为拥有一个从 10 开始并以 2 为增量的计数器。

于 2012-06-21T06:54:16.170 回答
1
(keep-indexed (fn [i el][el i]) (range 10))

或者

(keep-indexed #(vec [%2 %1]) (range 10))
(keep-indexed #(identity [%2 %1]) (range 10))
;([0 0] [1 1] [2 2] [3 3] [4 4] [5 5] [6 6] [7 7] [8 8] [9 9])
于 2012-06-19T16:33:34.360 回答
1

另外,请记住,在 Clojure 中使用索引通常是一种代码异味。

于 2012-06-20T15:09:22.137 回答