Повторяющиеся векторы в Clojure - PullRequest
6 голосов
/ 23 апреля 2010

Я новичок в Clojure. Я пытаюсь получить две копии векторных карточных мастей. Не-1001 * СУХОЙ способ, которым я могу придумать, это

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

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

Все, что я пробую, например

(replicate 2 suits)

приводит к двум отдельным векторам:

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

Как мне "сплющить" структуру?

Ответы [ 4 ]

7 голосов
/ 23 апреля 2010

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)
2 голосов
/ 23 апреля 2010

Небольшой эксперимент с 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)
2 голосов
/ 23 апреля 2010

(непроверенные!)

(apply concat (repeat 2 suits))

надеюсь, добьется цели.

concat, конечно, объединит 2 списка; apply может использоваться для перемещения данной функции в положение головы существующего списка для оценки.

1 голос
/ 24 апреля 2010
(take (* 2 (count suits)) (cycle suits))
...