2016-12-28 48 views
1

我希望能夠在循環內收集多個列表。Lisp:在循環中收集多個列表

我知道這可以做到沒有循環,但我想知道這是否也可以用循環。我想是這樣的:

(loop for var in list 
     (if (cond1 var) 
      (if (cond2 var) 
       collect into list1 
       collect into list2)) 
     finally (list list1 list2)) 

我得到錯誤的LOOP keyword is expected,我猜應該收集一個whenloop後立即使用。有什麼辦法可以解決這個問題嗎?

回答

3

你有一對夫婦的問題。

首先,如果你想把普通的Lisp代碼放到循環體中,你需要do關鍵字。但您可以使用dowhenif關鍵字。

其次,collect關鍵字要求您指定要收集到列表中的表達式,例如, collect var into list1

第三,您需要使用(return expression)才能從finally子句中的表單中返回值。

(loop for var in list 
    when (cond1 var) 
     if (cond2 var) 
     collect var into list1 
     else 
     collect var into list2 
    finally (return (list list1 list2))) 
+0

這兩個答案都很好,但這是我所需要的,使它全部運行!謝謝 –

2

信不信由你太多括號loop有它自己的小的子語言,它與Common Lisp s表達式有很大不同。

(loop :for var :in list 
     :when (cond1 var) 
     :if (cond2 var) 
      :collect var :into list1 
     :else 
      :collect var :into list2 
     :end 
     :end 
     :finally (return (list list1 list2))) 

另外我指定什麼:collect:finally只是評估,所以你需要使用(return ...),否則你可以期待nil

我使用關鍵字loop來區分它們與其他符號。這只是風格。縮進當然被忽略,只是爲了便於閱讀,但:end不是。但是在這種情況下,兩個:end關鍵字都是多餘的,因爲loop在沒有它們的情況下正確解析。

我決不是一個loop奇才..每次我得到的東西稍微複雜我傾向於使用Land of Lisp的元素週期表或Loop for black belts,從Practical Common Lisp一章。

Periodic table of Loop Macro