"mostly" 展平嵌套列表
"mostly" flatten a nested list
我有一个嵌套的 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?
谓词应该回答问题 "What determines when a sublist shouldn't be flattened?" 在您的情况下,这意味着以 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))
我有一个嵌套的 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?
谓词应该回答问题 "What determines when a sublist shouldn't be flattened?" 在您的情况下,这意味着以 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))