2010-04-23 2 views
6

Я новичок Clojure. Я пытаюсь получить две копии вектора карточных костюмов. Непостоянство DRY так, что я могу придумать этоПовторяющиеся векторы в Clojure

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

Там должно быть более функциональным способом (даже если это займет больше символов :-)). Что, если я хочу N раз? Какие-либо предложения?

Все вещи, я стараюсь, как

(replicate 2 suits) 

результатов в двух отдельных векторов:

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

Как "сплющивающихся" структуру?

+1

Там нет ничего нефункционального об использовании значения одного Var внутри 'def' формы СОЗДАНИЯ другой Вар. На самом деле, это естественная вещь, если второй Var зависит от первого. Конечно, если вам нужен общий метод конкатенации n копий seq, где n может быть или не быть заранее известно, тогда вам нужно лучшее решение (как показано в ответах здесь). –

+1

На самом деле, вот что я имел в виду (N копий). Я согласен с тем, что моя двукратная функция является «функциональной» - это просто непрактично, если я хочу 100 копий :-). – Ralph

ответ

7

concat дает ленивый SEQ. Если вы хотите, чтобы в конечном итоге с (не ленивого) вектора вместо:

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

'(doc replicate)' as of Clojure 1.7 говорит 'DEPRECATED: вместо этого используйте 'repeat'. ' –

2

Немного экспериментирования с РЕПЛ привело меня к этому решению:

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)) 
Смежные вопросы