我有一个嵌套的foo
,其中每个元素都是bar
,我想展平foo
而又不展平bar
。例如:
(special-flatten (foo (foo (bar 2) (bar 3)) (foo (bar 4) (bar 5)))) ;=>
((bar 2) (bar 3) (bar 4) (bar 5))
使用球拍的普通flatten
不起作用,因为我得到了(bar 2 bar 3 bar 4 bar 5)
。
foo
可以任意深度嵌套。
是否有使用球拍的方式?
如果您有一个确定何时不应展平子列表的谓词,则可以执行此操作。
;; An Element is a value for which element? returns true
;; element? : Any -> Boolean
(define (element? v)
...you-have-to-determine-this...)
此element?
谓词应回答以下问题:“由什么决定何时不应展平子列表?”在您的情况下,这意味着以bar
开头的内容,例如(bar 2)
和(bar 3)
。
;; An Element is a (cons 'bar Any)
;; element? : Any -> Boolean
(define (element? v)
(and (pair? v) (equal? (car v) 'bar)))
一旦定义了此element?
谓词,您就可以基于它创建扁平函数:
;; A NestedFooListofElement is one of:
;; - Element
;; - (cons 'foo [Listof NestedFooListofElement])
;; foo-list? : Any -> Boolean
(define (foo-list? v)
(and (list? v) (pair? v) (equal? (car v) 'foo)))
;; special-flatten : NestedFooListofElement -> [Listof Element]
(define (special-flatten nfle)
(cond
[(element? nfle) (list nfle)]
[(foo-list? nfle) (append-map special-flatten (rest nfle))]))
使用:
> (special-flatten '(foo (foo (bar 2) (bar 3)) (foo (bar 4) (bar 5))))
'((bar 2) (bar 3) (bar 4) (bar 5))