2010-04-23 29 views
6

Tôi là người mới sử dụng Clojure. Tôi đang cố gắng để có được hai bản sao của một vector của phù hợp với thẻ. Các phi DRY cách mà tôi có thể đưa ra làCác vectơ lặp lại trong Clojure

(def suits [:clubs :diamonds :hearts :spades]) 
(def two-times (concat suits suits)) 

Có phải là một cách thêm chức năng (ngay cả khi phải mất thêm các ký tự :-)). Nếu tôi muốn N lần thì sao? Bất kỳ đề xuất?

Tất cả những điều tôi cố gắng, như

(replicate 2 suits) 

kết quả trong hai vectơ riêng biệt:

([:clubs :diamonds :hearts :spades] [:clubs :diamonds :hearts :spades]) 

Làm thế nào để "san bằng" cấu trúc?

+1

Không có gì không có chức năng về việc sử dụng giá trị của một Var bên trong 'def' hình thức tạo ra một quần một Var khác. Trong thực tế, đó là điều tự nhiên để làm nếu Var thứ hai phụ thuộc vào lần đầu tiên. Tất nhiên nếu bạn muốn có một phương pháp chung để nối n bản sao của một seq, trong đó n có thể hoặc có thể không được biết trước, thì bạn cần một giải pháp tốt hơn (như được tìm thấy trong các câu trả lời ở đây). –

+1

Thực ra, đó là ý của tôi (N bản sao). Tôi đồng ý rằng chức năng hai lần của tôi là "chức năng" - nó chỉ là không thực tế nếu tôi muốn 100 bản sao :-). – Ralph

Trả lời

7

concat mang đến cho bạn một seq lười biếng. Nếu bạn muốn kết thúc với một (không lười biếng) vector thay vì:

user> (into suits suits) 
[:clubs :diamonds :hearts :spades :clubs :diamonds :hearts :spades] 
user> (reduce into (replicate 2 suits)) 
[:clubs :diamonds :hearts :spades :clubs :diamonds :hearts :spades] 

Tùy thuộc việc bạn đang truy cập này bằng cách chỉ số nhiều hoặc lặp lại trên nó, hoặc là một vector hoặc một seq có thể thích hợp hơn.

Luôn luôn cycle quá, nếu bạn muốn có một bất tận (lười biếng) dòng của các yếu tố lặp đi lặp lại:

user> (take 9 (cycle suits)) 
(:clubs :diamonds :hearts :spades :clubs :diamonds :hearts :spades :clubs) 
+0

Tôi cũng đã đưa ra (mất 8 (phù hợp với chu kỳ)). Dường như để làm việc, nhưng tôi đã phải tìm phần "8" ra bản thân mình, mà không cần sự giúp đỡ của một máy tính :-). – Ralph

2

(chưa được kiểm tra!)

(apply concat (repeat 2 suits)) 

sẽ hy vọng làm các trick.

concat dĩ nhiên sẽ nối 2 danh sách; apply có thể được sử dụng để buôn lậu một chức năng cụ thể vào vị trí đầu của danh sách hiện có để đánh giá.

+2

Sửa tên hàm ('assoc' ->' apply'). –

+0

Ồ, thật ngu ngốc của tôi. Tôi sử dụng 'áp dụng' tất cả các thời gian, bạn nghĩ rằng tôi muốn biết tên của nó bây giờ ... Cảm ơn bạn đã sửa chữa! –

+0

'(doc replicate)' như của Clojure 1.7 nói 'KHÔNG DÙNG: Sử dụng 'lặp lại' thay thế.' –

2

Một chút thử nghiệm với REPL đưa tôi đến với giải pháp này:

user=> (def suits [:clubs :diamonds :hearts :spades]) 
#'user/suits 
user=> suits 
[:clubs :diamonds :hearts :spades]  
user=> (reduce concat (replicate 2 suits)) 
(:clubs :diamonds :hearts :spades :clubs :diamonds :hearts :spades) 
1
(take (* 2 (count suits)) (cycle suits)) 
Các vấn đề liên quan