2012-10-09 57 views
2

「定義了一個程序'reduce-per-key',它是一個過程reducef和一個關聯列表,每個關鍵字與一個列表配對。輸出是一個相同結構的列表,除了每個關鍵字現在與應用reducef其關聯列表」如何在方案中編寫按鍵減少功能?

我已經寫的結果‘地圖每個鍵’和‘組逐鍵’:

(define (map-per-key mapf lls) 
    (cond 
    [(null? lls) '()] 
    [else (append (mapf (car lls))(map-per-key mapf (cdr lls)))])) 

(define (addval kv lls) 
    (cond 
    [(null? lls) (list (list (car kv)(cdr kv)))] 
    [(eq? (caar lls) (car kv)) 
    (cons (list (car kv) (cons (cadr kv) (cadar lls)))(cdr lls))] 
    [else (cons (car lls)(addval kv (cdr lls)))])) 

(define (group-by-key lls) 
    (cond 
    [(null? lls) '()] 
    [else (addval (car lls) (group-by-key (cdr lls)))])) 

怎麼會有我寫下一步,'按鍵減少'?我也無法確定它是否需要兩個參數或三個參數。

到目前爲止,我想出了:

(define (reduce-per-key reducef lls) 
    (let loop ((val (car lls)) 
      (lls (cdr lls))) 
    (if (null? lls) val 
     (loop (reducef val (car lls)) (cdr lls))))) 

然而,與一個測試用例,如:

(reduce-per-key 
    (lambda (kv) (list (car kv) (length (cadr kv)))) 
    (group-by-key 
    (map-per-key (lambda (kv) (list kv kv kv)) xs))) 

我收到了不正確的參數個數,但是當我嘗試寫它有三個參數,我也收到這個錯誤。任何人都知道我在做什麼錯了?

回答

1

您的解決方案是很多比它需要更復雜,並且有幾個錯誤。事實上,正確的答案很簡單,不需要定義新的輔助程序。嘗試在這個骨架的解決方案的工作,只是填寫了空白:

(define (reduce-per-key reducef lls) 
    (if (null? lls)  ; If the association list is empty, we're done 
     <???>    ; and we can return the empty list. 
     (cons (cons <???> ; Otherwise, build a new association with the same key 
        <???>) ; and the result of mapping `reducef` on the key's value 
      (reduce-per-key <???> <???>)))) ; pass reducef, advance the recursion 

請記住,有超過列表映射功能的內置程序。測試這樣的:每個協會是由一個鍵(car部分)和一個列表作爲它的值(cdr部分)

(reduce-per-key (lambda (x) (* x x)) 
       '((x 1 2) (y 3) (z 4 5 6))) 

> '((x 1 4) (y 9) (z 16 25 36)) 

通知。例如:

(define an-association '(x 3 6 9)) 
(car an-association) 
> 'x  ; the key 
(cdr an-association) 
> '(3 6 9) ; the value, it's a list 

作爲最後一個問題,這個名字reduce-per-key是有點誤導,map-per-key會很多更合適,因爲這過程可以容易地使用map表示...但剩下的作爲一個練習讀者。

UPDATE:

現在,你已經找到了解決辦法,我可以使用map提出一個更簡潔的選擇:

(define (reduce-per-key reducef lls) 
    (map (lambda (e) (cons (car e) (map reducef (cdr e)))) 
     lls)) 
+0

我相當肯定我已經正確填寫的空白,除了對於(;對密鑰值映射'reducef'的結果)是 –

+0

是(reducef(cdr lls))? @ÓscarLópez –

+0

不用,只需使用內置的'map'程序(在您的Scheme解釋器的文檔中閱讀它)。不要重新發明輪子! –