2010-04-23 5 views
6

나는 Clojure 초보자입니다. 카드 소송의 벡터 사본 2 부를 얻으려고합니다. 내가 가지고 올 수있는 비 DRY 방법은반복판에 Clojure

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

이 (가 :-) 더 많은 문자를 취하더라도) 더 기능적인 방법이 있어야한다. 내가 N 시간을 원한다면? 어떤 제안?

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

가 어떻게 구조를 "결합"않습니다 : 두 개의 벡터에서

(replicate 2 suits) 

결과 같은

내가하려고하는 일의 모든

?

+1

은'def' 폼 만들기 내부에 하나 바르의 값을 사용하는 방법에 대한 비 기능은 어디에도 없습니다 다른 Var. 사실, 두 번째 Var가 첫 번째 Var에 의존하는 경우 자연스러운 일입니다. 물론 n을 사전에 알고있을 수도 있고 그렇지 않을 수도있는 seq의 n 개의 사본을 연결하는 일반적인 방법을 원한다면 더 나은 해결책이 필요합니다 (여기의 답에서 찾을 수 있습니다). –

+1

사실, 그것이 내가 의미하는 바입니다 (N 부). 나는 나의 2 배 기능이 "기능적"이라는 것에 동의한다. 나는 100 부를 원한다면 실용적이지 않다. :-). – Ralph

답변

7

concat 당신에게 게으른 서열을 제공합니다. 당신이 대신 (비 지연) 벡터와 종료 할 경우

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] 

는 벡터 또는 서열이 더 적합 할 수 있습니다 중 하나가 인덱스에 의해 많은이 접근하거나 반복하고 있는지 따라. 당신이 반복 요소의 끝없는 (게으른) 스트림을 원하는 경우

도 항상 cycle있다 :

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

나는 또한 (8을 잡는다 (한 벌을 싸운다)). 일하는 것처럼 보였지만, 나는 컴퓨터의 도움을받지 않고 "8"부분을 스스로 알아 내야 만했다. – Ralph

2

(안된!)

(apply concat (repeat 2 suits)) 

트릭을 할 희망합니다.

concat 물론 2 개의 목록을 연결합니다. apply은 주어진 함수를 평가를 위해 기존 목록의 머리 위치로 밀입시키는 데 사용될 수 있습니다.

+2

함수 이름을 수정했습니다 ('assoc' ->'apply'). –

+0

오, 나 얼마나 바보. 나는 항상'apply'를 사용합니다, 당신은 내가 지금 그 이름을 안다고 생각할 것입니다 ... 고침을 가져 주셔서 감사합니다! –

+0

Clojure 1.7의'(doc replicate)'에''DEPRECATED : 대신에 'repeat'을 사용하십시오. " –

2

REPL 함께 작은 실험이 솔루션에 나를 인도 :

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))