我有一个嵌套的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
可以任意深度嵌套。
有没有一种球拍方式?
答案 0 :(得分:1)
如果您有一个确定何时不应展平子列表的谓词,则可以执行此操作。
;; 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?
谓词,您就可以基于它创建一个flatten函数:
;; 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))