scheme - "大部分" 展平嵌套列表
问题描述
我有一个嵌套foo
,其中每个元素都是 a bar
,我想在不展平foo
s 的情况下展平bar
s。
例如:
(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?
定义了这个谓词,你就可以基于它创建一个 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))
推荐阅读
- javascript - UTC 与本地时间的时差
- scala - 使用广播变量或使用 RDD 过滤器计算两个节点邻居的交集?
- php - [Route: havence.automail.edit] [URI: havence/automail/{automail}/edit] 缺少必需的参数
- git - 重置提交被计为贡献(根据提交计数)
- javascript - PHP 提交 POST
- python - 树莓派 3 上的 TensorFlow 显示“超过总内存的 10%”错误
- python - 如何使用 linux/python 在 CSV 文件中创建派生列?
- c# - NSwag MSBuild“路径'/api/Account'上的方法'get'被多次注册”
- aws-step-functions - 通过 Step Function 调用 lambda 函数时可以指定 lambda 别名吗?
- twilio - Twilio 支持文档中关于美国号码不能轻易识别为手机号码的声明是否不正确?