2012-06-19 24 views
6

Tôi muốn để lặp qua một bộ sưu tập và đồng thời cũng duy trì một bộ đếm cũThực hiện một truy cập trong cho

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

Tôi muốn 'y' để đại diện cho truy cập, vì vậy cho mọi phần tử đầu ra là ([0 0] [1 1] [2 2] ...). Làm thế nào để làm điều đó?

Trả lời

12

Bạn có thể sử dụng indexed từ clojure.contrib.seq. Ví dụ:

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

Bạn cũng có thể sử dụng map-indexed. Ví dụ:

(map-indexed vector "foobar") => ([0 \f] [1 \o] [2 \o] [3 \b] [4 \a] [5 \r]) 
6

Sử dụng map-indexed, như lời khuyên của Simeon. Trong for bối cảnh nó thuận tiện để sử dụng destructuring để dễ dàng truy cập đến tất cả các truy cập và các yếu tố bộ sưu tập:

(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]) 
1
(keep-indexed (fn [i el][el i]) (range 10)) 

hoặc

(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]) 
1

Ngoài ra, hãy nhớ rằng việc sử dụng các chỉ số trong Clojure nói chung là một mùi mã.

2

Tôi tính nếu câu hỏi này vẫn chưa được đánh dấu là "đã trả lời", có thể có điều gì đó khác mà bạn đang tìm kiếm và có thể là sự linh hoạt để xác định bộ đếm của riêng bạn.

Tôi đồng ý với những người khác về vấn đề cụ thể mà bạn phác thảo, map-indexed là cách để thực hiện. Tuy nhiên, nếu bạn nhấn mạnh vào việc sử dụng for, tôi muốn giới thiệu một cái gì đó như thế này:

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

Rafal có một câu trả lời rất giống nhau, ngoại trừ việc truy cập sẽ luôn bắt đầu từ con số không và tăng lên 1. Trong phiên bản của tôi bạn có thể xác định truy cập của bạn khi bạn thấy phù hợp. Ví dụ: bằng cách thay đổi số (iterate inc 0) ở trên thành (iterate #(+ 2 %) 10), bạn có thể có bộ đếm bắt đầu ở mức 10 và tăng thêm 2.

Các vấn đề liên quan