2016-01-31 3 views
1

Это вопрос о том, как правильно собирать результаты из вложенного цикла for в Clojure. Предположим, что вы хотите создать последовательность всех векторов [i j] где 0<=j<i<4Как создать одну ленивую последовательность из вложенного цикла цикла в Clojure

Следующий код

(for [i (range 1 4)] 
    (for [j (range i)] 
    [i j] 
) 
) 

производит

(([1 0]) ([2 0] [2 1]) ([3 0] [3 1] [3 2])) 

но то, что я действительно хочу, чтобы получить является

([1 0] [2 0] [2 1] [3 0] [3 1] [3 2]) 

Каков правильный способ сделать это?

Обратите внимание, что меня не интересует эта конкретная последовательность. Моя цель здесь - научиться собирать результаты из вложенного цикла for, который мне нужен для более сложной проблемы.

+0

FYI 'for' в Clojure не нравится' for' в C или Java. Наличие для вложенных в другое для довольно необычно. Clojure 'for' - функция распознавания списка, она помогает вам создать список. См. Python list comprehension для [примеров] (http://carlgroner.me/Python/2011/11/09/An-Introduction-to-List-Comprehensions-in-Python.html). – kawas44

+0

Спасибо. Я попробовал подход, который вы предлагаете, и это действительно чище. –

ответ

5

Не гнездятся две петли, а использовать одну петлю с двумя итераторов:

2

Предполагая, что вы имеют использовать вложенную для петель, apply concat является preferred way to flatten a sequence by one level

=> (apply concat 
     (for [i (range 1 4)] 
      (for [j (range i)] 
      [i j]))) 

([1 0] [2 0] [2 1] [3 0] [3 1] [3 2]) 

@Oin's solution всегда предпочтительнее, если внутренний цикл не зависит от внешнего контура.

+0

Спасибо. Это именно то, что я искал. –

Смежные вопросы