如何忽略方案中的内部列表?

时间:2013-01-13 15:49:20

标签: list scheme racket

我编写了一个过程,从列表中获取每个值并返回一个列表,其中每个值都为-1(例如)

(define (Set-list a val)
  (if ( null? a) (list)
    (append (list val) (Set-list (cdr a) val))
))

(Set-list '(2 3 4) -1) //returns '(-1 -1 -1)
(Set-list '(A(2 3) B(2 3) C(2 3)) -1) // returns '(-1 -1 -1 -1 -1 -1)

如何让它返回-1 -1 -1?我不想得到名单的内部成员?

4 个答案:

答案 0 :(得分:1)

也许你会混淆列表在Scheme中的工作方式。此列表:'(A(2 3) B(2 3) C(2 3)) 与此列表完全相同'(A (2 3) B (2 3) C (2 3))。也就是说,它是一个六元素列表。如果您想将符号和数字的组合视为单个元素,请将它们打包在一个列表中:'((A 2 3) (B 2 3) (C 2 3))

作为旁注,编写set-list过程的方式不是惯用的,特别是在构建列表时使用append不是将元素放在头部的最佳方法,请使用{{ 1}}为此。这是编写程序的更好方法:

cons

现在,按照我上面的建议,这是如何运作的:

(define (set-list a val)
  (if (null? a)
      '()
      (cons val
            (set-list (cdr a) val))))

<强>更新

现在,如果对列表工作的方式确实没有误解,并且您只想用给定值替换列表中的所有子列表,这将起作用:

(set-list '((A 2 3) (B 2 3) (C 2 3)) -1)
=> '(-1 -1 -1)

答案 1 :(得分:1)

由于Anton提到了一个惯用的解决方案,这是我在Racket中的惯用解决方案(我相信使用高阶函数,如mapfilter-not和可论证的const是比手动循环和过滤更惯用。 : - )

(define (set-list lst val)
  (map (const val) (filter-not list? lst)))

(球拍确实提供filter-map,但它以与我们想要的相反的顺序应用filtermap。)

答案 2 :(得分:0)

这是我的尝试(可能不是惯用方案,请注意,使用append执行此操作无论如何都是错误的)。我假设您要完全跳过子列表,正如您在评论中所解释的那样。

(define (Set-list a val)
  (if (null? a)
      (list)     
      (append (if (list? (car a))
                  (list)
                  (list val))
              (Set-list (cdr a) val))))

答案 3 :(得分:0)

如果要创建一个值列表,其长度与给定列表长度相同,

(define (set-list list value)
    (build-list (length list) (lambda (x) value)))

所以,

(set-list '(2 3 4) -1) //returns '(-1 -1 -1)
(set-list '(A (2 3) B (2 3) C (2 3)) -1) // returns '(-1 -1 -1 -1 -1 -1)
(set-list '(2 3 4) -2) //returns '(-2 -2 -2)
(set-list '(A (2 3) B (2 3) C (2 3)) -2) // returns '(-2 -2 -2 -2 -2 -2)