2015-11-04 47 views
0

我想申請(map fun list)到列表或列表的列表的內部列表一般,這樣的功能可以(inner-map proc list)做到以下幾點:走進列表清單?

plain list(1d): 
    (inner-map even? '(1 2 3)) 
    => (#f #t # f) 

list of lists(2d): 
    (inner-map even? '((1 2 3) (1 2 3) (1 2 3)) 
    => ((#f #t #f) (#f #t #f) (#f #t #f)) 

list of lists of lists (3d): 
    (inner-map even? '(((1 2 3) (1 2 3) (1 2 3)) 
         ((1 2 3) (1 2 3) (1 2 3)) 
         ((1 2 3) (1 2 3) (1 2 3)))) 
    => (((#f #t #f) (#f #t #f) (#f #t #f)) ((#f #t #f) (#f #t #f) (#f #t #f)) ((#f #t #f) (#f #t #f) (#f #t #f))) 
ad nauseum 

雖然不知道在一個通用的,我可以把它在時間列表中的一個維度的工作,像這樣:

2d list: 
(define (inner-map proc lis)  
    (map (lambda (y) 
     (map (lambda (x) 
       (proc x)) 
       y)) 
     lis)) 


3d list: 
(define (inner-map proc lis) 
    (map (lambda (z) 
     (map (lambda (y) 
       (map (lambda (x) 
         (proc x)) 
        y)) 
       z)) 
     lis)) 

And even 4d list structs: 
(define (inner-map proc lis) 
    (map (lambda (l) 
     (map (lambda (k) 
       (map (lambda (j) 
         (map (lambda (i) 
           (proc i)) 
          j)) 
        k)) 
       l)) 
     lis)) 

所以,使其成爲直到你達到一個列表中,您將需要進行遞歸調用,巢(map (lambda (var) ...var))š更深的任何深度的明細表總的工作原子能。雖然這不工作,這是我的問題,刺:

(define (inner-map proc lis) 
    (map (lambda (x) 
     (cond ((atom? (car lis)) (proc x))) 
     (else (inner-map proc x))) 
     lis)) 

編輯:所以,當我還在學習高階函數,將一個倍或遞歸倍是合適的?

回答

2

您的inner-map函數唯一的問題是(atom? (car lis))應該是(atom? x)。在錯誤的地方也有一些小括號。考慮:

(define (inner-map proc lis) 
    (map (lambda (x) 
     (cond ((atom? x) (proc x)) 
       (else (inner-map proc x)))) 
     lis)) 
+0

你打敗了我。 –

+0

這不起作用,你的內部地圖也會在某處丟失一個關閉的位置,如果你把它放在最後,它會關閉,但我不確定這是否是你想要放置的地方。如果我把close paren放在最後,所以最後看起來像'lis))),並且調用'(inner-map even?li)'where('define li(list(list 1 2 3))(list 4 5 6)),我得到了「#程序#[編譯過程64(映射」列表#x6f)#xf#x22aced7]已被調用1個參數;它至少需要2個參數。 – Anandamide

+0

抱歉沒關係,它確實工作,但只有當你添加缺少的paren,以便'(else(inner-map proc x))))' – Anandamide

1

@ dan-d已經用正確的代碼回答了您的問題。我將添加以下分析。

由於變量lis位於lambda範圍內,所以在語法上起作用,儘管算法失敗,所以您編譯的最後一段代碼會被編譯。函數map對列表中的每個元素進行操作,這意味着傳遞給lambda函數的x(迭代)是列表中的每個元素。同時,(car lis)始終抓取lis的第一個元素,因此您只能根據第一個元素的類型而不是當前元素的類型遞歸調用procx

這是錯誤。

Scheme中lambda函數的功能來自捕捉其範圍內所有變量的當前狀態的能力。對lis的引用雖然沒有傳入你的lambda,但是從lambda範圍之外,並且在inner-map函數的範圍之內。