球拍:如何将两个列表与 f 成对组合
Racket: How to combine two lists pairwise with f
我实现了一个函数 (combine f n l1 l2),它将两个列表与 f 和 returns 成对组合成一个列表:
(check-expect (combine string-append "" '("1" "2" "3") '("4" "5" "6")) '("14" "25" "36"))
(check-expect (combine + 0 '(1 2 3) '(4 5 6)) '(5 7 9))
(define (combine f n l1 l2)
(if (empty? l1) '()
(cons (foldr f n (first (zip l1 l2)))
(combine f n (rest l1) (rest l2)))))
它使用了我之前实现的(zip l1 l2)函数:
(check-expect (zip '(1 2 3 0) '(4 5 6))'((1 4) (2 5) (3 6)))
(define (zip l1 l2)
(local
[(define (take lst n)
(if (zero? n)
'()
(cons (first lst)
(take (rest lst)(- n 1)))))
(define min-lsts
(min (length l1) (length l2)))]
(foldr (lambda (e1 e2 acc) (cons (list e1 e2) acc)) '() (take l1 min-lsts) (take l2 min-lsts))))
(combine f n l1 l2) 按预期工作,但有没有办法将其更改为 (combine f l1 l2) 不期望 n 但仍使用 foldr?
提前致谢!
只要你总是有两个参数,你就可以用 foldr
替换递归,直接使用这两个参数:
(define (combine f l1 l2)
(foldr (lambda (a1 a2 acc)
(cons (f a1 a2)
acc))
'()
l1
l2))
而且 zip 的实现过于复杂。它可以做得更简单:
(define (zip l1 l2)
(map list l1 l2))
我实现了一个函数 (combine f n l1 l2),它将两个列表与 f 和 returns 成对组合成一个列表:
(check-expect (combine string-append "" '("1" "2" "3") '("4" "5" "6")) '("14" "25" "36"))
(check-expect (combine + 0 '(1 2 3) '(4 5 6)) '(5 7 9))
(define (combine f n l1 l2)
(if (empty? l1) '()
(cons (foldr f n (first (zip l1 l2)))
(combine f n (rest l1) (rest l2)))))
它使用了我之前实现的(zip l1 l2)函数:
(check-expect (zip '(1 2 3 0) '(4 5 6))'((1 4) (2 5) (3 6)))
(define (zip l1 l2)
(local
[(define (take lst n)
(if (zero? n)
'()
(cons (first lst)
(take (rest lst)(- n 1)))))
(define min-lsts
(min (length l1) (length l2)))]
(foldr (lambda (e1 e2 acc) (cons (list e1 e2) acc)) '() (take l1 min-lsts) (take l2 min-lsts))))
(combine f n l1 l2) 按预期工作,但有没有办法将其更改为 (combine f l1 l2) 不期望 n 但仍使用 foldr?
提前致谢!
只要你总是有两个参数,你就可以用 foldr
替换递归,直接使用这两个参数:
(define (combine f l1 l2)
(foldr (lambda (a1 a2 acc)
(cons (f a1 a2)
acc))
'()
l1
l2))
而且 zip 的实现过于复杂。它可以做得更简单:
(define (zip l1 l2)
(map list l1 l2))