Zuerst, wenn alles, was Sie wollen, eine cartesian-product
Funktion ist, können Sie cartesian-product
von racket/list
verwenden.
> (cartesian-product
(list '(10 11) '(20 21))
(list '('u 'v) '('p 'q)))
'(((10 11) ('u 'v)) ((10 11) ('p 'q)) ((20 21) ('u 'v)) ((20 21) ('p 'q)))
Ihr Testfall ist etwas anders als das, weil Ihr Testfall der inneren Listen Spleißstellen und dies nicht tut. Aber wenn Sie das brauchen, können Sie es einfach mit (map append* ...)
beheben. Die Funktion append*
flacht eine Liste von Listen um eine Ebene nach unten ab.
> (define (mix-rows rows1 rows2)
(map append* (cartesian-product rows1 rows2)))
> (mix-rows
(list '(10 11) '(20 21))
(list '('u 'v) '('p 'q)))
'((10 11 'u 'v) (10 11 'p 'q) (20 21 'u 'v) (20 21 'p 'q))
Obwohl, wenn Sie es von Grund auf neu entwerfen wollen, das Problem bei der Implementierung ist, dass foldr
erwartet eine Funktion (X Y -> Y)
, eine Zwei-Argument Funktion, aber sie gab es eine Funktion (Row -> Row)
, eine ein Argument Funktion. Du könntest das beheben, aber von dem, was ich sehen kann, brauchst du überhaupt keinen foldr
. Wahrscheinlich hast du dort auch eine map
gemeint.
(define mix-rows
(lambda (rows1 rows2)
(map (lambda (row1)
(map (lambda (row2)
(append row1 row2))
rows2))
rows1)))
Obwohl dies Ihr Testfall noch ausfällt, produziert
> (mix-rows
(list '(10 11) '(20 21))
(list '('u 'v) '('p 'q)))
'(((10 11 'u 'v) (10 11 'p 'q)) ((20 21 'u 'v) (20 21 'p 'q)))
Um dieses zusätzliche Schicht von verschachtelten Listen loszuwerden, können Sie append*
verwenden Sie diese Liste von Listen eine Ebene nach unten zu glätten.
;; Signature: mix-rows(rows1 rows2)
;; Purpose: returns a list of rows of the cartesian product of both rows
;; Type: [ List(Row) * List(Row) -> List(Row) ]
;; Tests:
;; (mix-rows (list '(10 11) '(20 21)) (list '('u 'v) '('p 'q)))
;; ==> ((10 11 'u 'v)
;; (10 11 'p 'q)
;; (20 21 'u 'v)
;; (20 21 'p 'q))
(define mix-rows
(lambda (rows1 rows2)
(append*
(map (lambda (row1)
(map (lambda (row2)
(append row1 row2))
rows2))
rows1))))
Wenn Sie jedoch ein echtes cartesianischen Produkt wünschen, ohne die Zeilen Spleißen, können Sie sie beheben, indem (append row1 row2)
zu (list row1 row2)
ändern.
(define mix-rows
(lambda (rows1 rows2)
(append*
(map (lambda (row1)
(map (lambda (row2)
(list row1 row2))
rows2))
rows1))))
Dann entspricht es was cartesian-product
tut.
Sie wahrscheinlich nicht zum doppelten Zitat "uvpq", verwenden Sie einfach ''(uv)' und '' (pq)', die gezuckerte Versionen von '(Liste (Zitat u) (Zitat v)) und '(Liste (Zitat p) (Zitat q))' – naomik