2013-02-18 117 views
2

在許多情況下,我想通過遞歸函數做出列表,我找不到正確的方式如何做到這一點。如何通過遞歸進行列表?

例如(不是有用但最短我可以找到)我想從列表中逐個獲取元素並創建與第一個列表相同的新列表。

(defn f [x] (list 
      (first x) 
      (if (not= (rest x) '()) 
      (f (rest x)) 
      '()  
))) 

(f '(1 2 3)) 

我想

(1 2 3) 

,但我得到

(1 (2 (3()))) 

我想不使用壓平。 例如,這種輸入

(f '([1 1] [2 2] [3 3])) 

將被夷爲平地。

回答

4

更換listcons

(defn f [x] 
    (cons (first x) 
     (if (not= (rest x) '()) 
      (f (rest x)) 
      '()))) 

操作(list x y)返回列表兩個元素:(x y)。操作(cons x y)返回列表哪個頭(即,第一個元素)是x而尾部(列表的其餘部分)是y,其中y應該列出它自己。

+0

不應該有「y必須是列表」而不是「y應該是列表」? (0 1) (cons 1 1) java.lang.IllegalArgumentException:不知道如何創建ISeq:java.lang.Integer(NO_SOURCE_FILE:0) (cons 1 [1]) (11) – boucekv 2013-02-18 11:14:21

+0

@boucekv This取決於Lisp的風味。在一些口味中,對可以由兩個非零原子組成。 – 2013-02-18 11:29:53

+3

如果傳遞一個空列表,這將會出現問題。在採用第一個元素之前檢查一個空列表會更好:'(if(= x'())'()(cons(first x)(f(rest x))))'。 – 6502 2013-02-18 14:12:48