升级列表清单

时间:2019-03-30 11:31:50

标签: scheme racket

我正在尝试在球拍中拉平由列表和列表组成的列表。原始列表如下:

'(((a 1) (b 2)) (c 3) ((d 4) (e 5)))

我需要像这样

'((a 1) (b 2) (c 3) (d 4) (e 5))

我尝试过拼合,连接等,但得到的却是不同的东西:

(define KK '(((a 1)(b 2))(c 3)((d 4)(e 5))))

(map(lambda(x)(if (list? x) x (list x)))(concatenate KK))

'((a 1) (b 2) (c) (3) (d 4) (e 5))

(map(lambda(x)x)(concatenate KK))

'((a 1) (b 2) c 3 (d 4) (e 5))

(map(lambda(x)(if (list? (car x)) (ormap(lambda(y)(when (list? y) y)) x) x))KK)

'((a 1) (c 3) (d 4))

(map(lambda(x)(if (list? (car x)) (andmap(lambda(y)(when (list? y) y)) x) 
x))KK)

'((b 2) (c 3) (e 5))

我越接近最后两个,但我缺少值,因为它是一个布尔映射。 Map将结果打包在一个列表中。

编辑:我的主要问题是列表是由一个函数创建的,该函数根据输入而定,输出是单个列表还是2到n个列表的列表:

让一个称为H的列表由2到n个元素组成。假设SPECS是一个由列表组成的列表,其中包含与条件C匹配的H元素的可能组合。例如:

H='(a 1)

因此,作为'*一个在语义上表示野车的符号,让H中所有元素的组合为:

HHs='((* *) (a *)(* 1) (a 1))

所以SPECS是满足某些条件的HH,例如:'(((a )( 1))

(map (lambda(S)(when  (<condition>)(set! NEWSET (append NEWSET S))))SPECS)

如果我追踪到S,我会看到:

S1: (((*) (-inf.0 9) (2 +inf.0) (*)) ((*) (9 30) (2 +inf.0) (*)))
S2: ((*) (-inf.0 30) (2 +inf.0) (*))
S3: (((*) (-inf.0 30) (2 +inf.0) (no)) ((*) (-inf.0 30) (2 +inf.0) (si)))
S4: (((soleado) (-inf.0 30) (*) (*)) ((nublado) (-inf.0 30) (*) (*)) ((lluvioso) (-inf.0 30) (*) (*)))

因此,如果我将它们包装在列表中,我将拥有:

'((((*) (-inf.0 9) (2 +inf.0) (*)) ((*) (9 30) (2 +inf.0) (*)))
   ((*) (-inf.0 30) (2 +inf.0) (*))
   (((*) (-inf.0 30) (2 +inf.0) (no)) ((*) (-inf.0 30) (2 +inf.0) (si)))
   (((soleado) (-inf.0 30) (*) (*)) ((nublado) (-inf.0 30) (*) (*)) ((lluvioso) (-inf.0 30) (*) (*))))

但是我需要:

'(((*) (-inf.0 9) (2 +inf.0) (*)) ((*) (9 30) (2 +inf.0) (*))((*) (-inf.0 30) (2 +inf.0) (*))((*) (-inf.0 30) (2 +inf.0) (no)) ((*) (-inf.0 30) (2 +inf.0) (si))((sunny) (-inf.0 30) (*) (*)) ((cloudy) (-inf.0 30) (*) (*)) ((rainy) (-inf.0 30) (*) (*)))

((中包含列表中的元素,这只是我的算法的语义)。

致谢

3 个答案:

答案 0 :(得分:2)

对于任意嵌套列表的一般情况,没有一个单行的内置过程可以解决此问题。这是一个使用显式循环的可能解决方案,假设该列表在所有级别上都包含两个元素的子列表:

(define (level-out lst)
  (let loop ([lst (flatten lst)])
    (if (empty? lst)
        '()
        (cons (list (first lst) (second lst))
              (loop (rest (rest lst)))))))

它按预期工作:

(level-out '(((a 1) (b 2)) (c 3) ((d 4) (e 5))))
=> '((a 1) (b 2) (c 3) (d 4) (e 5))

(level-out '((((((a 1)))))))
=> '((a 1))

(level-out '())
=> '()

(level-out '((a 1) (b 2) (c 3) (d 4) (e 5)))
=> '((a 1) (b 2) (c 3) (d 4) (e 5))

答案 1 :(得分:2)

这是使用match的解决方案。请注意,这里的假设是我们要提升的内部列表是两件事的列表。

    <div id="UHD" ng-controller="Content-folders-4K">
    <div id="UHD-frames" class="d-flex">
        <div ng-repeat="friend in UHD" class="row">
            <div id="img-frame" class="col-md-3 col-sm-6 col-xs-12">
                <a href="/4k/{{friend.name}}.html">
                    <img alt="{{friend.name}}" src="assets/images/4k-thumbs/{{friend.name}}.jpg" class="img-fluid">
                </a>
                <p class="font-weight-bold text-center">{{friend.name}}</p>
            </div>
        </div>
    </div>
</div>

答案 2 :(得分:1)

如果您有一个确定何时不应展平子列表的谓词,则可以执行此操作。

;; An Element is a value for which element? returns true
;; element? : Any -> Boolean
(define (element? v)
  ...you-have-to-determine-this...)

element?谓词应回答以下问题:“什么决定什么时候不应该展平子列表?”就像(z 0)(a 1)(b 2)等在您的示例中未变平。到目前为止,其他答案都假定确定这些内容的是两个元素的列表,但是您已经说过子列表是1到n个元素。无论将它们与普通嵌套列表区分开的形状是什么,都应定义element?来识别。

如果您确定此element?谓词,则可以基于该谓词进行扁平化函数:

;; A NestedListofElement is one of:
;;  - Element
;;  - [Listof NestedListofElement]

;; flatten-elements : NestedListofElement -> [Listof Element]
(define (flatten-elements nle)
  (cond
    [(element? nle) (list nle)]
    [(list? nle)    (append-map flatten-elements nle)]))