走进列表清单?

时间:2015-11-04 04:31:25

标签: recursion scheme map-function

我想将(map fun list)一般应用于列表或列表列表的内部列表,以便函数(inner-map proc list)可以执行以下操作:

plain list(1d):
   (inner-map even? '(1 2 3))
   => (#f #t # f)

list of lists(2d):
   (inner-map even? '((1 2 3) (1 2 3) (1 2 3))
   => ((#f #t #f) (#f #t #f) (#f #t #f))

list of lists of lists (3d):
   (inner-map even? '(((1 2 3) (1 2 3) (1 2 3))
                      ((1 2 3) (1 2 3) (1 2 3))
                      ((1 2 3) (1 2 3) (1 2 3))))
   => (((#f #t #f) (#f #t #f) (#f #t #f)) ((#f #t #f) (#f #t #f) (#f #t #f)) ((#f #t #f) (#f #t #f) (#f #t #f)))
 ad nauseum

虽然对通用设备不确定,但我可以让它同时适用于列表的一个维度:

2d list:
(define (inner-map proc lis)       
  (map (lambda (y)
         (map (lambda (x)
                (proc x))
              y))
       lis))


3d list:
(define (inner-map proc lis)
  (map (lambda (z)
         (map (lambda (y)
                (map (lambda (x)
                       (proc x))
                     y))
              z))
       lis))

And even 4d list structs:
(define (inner-map proc lis)
  (map (lambda (l)
         (map (lambda (k)
                (map (lambda (j)
                       (map (lambda (i)
                              (proc i))
                            j))
                     k))
              l))
       lis))

因此,为了使其适用于任何深度的列表,您需要进行递归调用,使(map (lambda (var) ...var))更深的嵌套直到达到原子列表。虽然这不起作用,但这是我对这个问题的准备:

(define (inner-map proc lis)
  (map (lambda (x)
         (cond ((atom? (car lis)) (proc x)))
         (else (inner-map proc x)))
       lis))

编辑:因此,虽然我仍然在学习更高阶函数,但折叠或递归折叠是否合适?

2 个答案:

答案 0 :(得分:2)

inner-map功能的唯一问题是(atom? (car lis))应为(atom? x)。在错误的地方也有密切的括号。考虑:

(define (inner-map proc lis)
  (map (lambda (x)
         (cond ((atom? x) (proc x))
               (else (inner-map proc x))))
       lis))

答案 1 :(得分:1)

@ dan-d已使用正确的代码回答了您的问题。我将添加以下分析。

你的最后一块代码编译是因为变量lis在lambda的范围内,所以(atom? (car lis))在语法上有效,尽管在算法上失败了。函数map对列表中的每个元素进行操作,这意味着传递给lambda函数的x是(迭代地)列表中的每个元素。同时,(car lis)始终抓取lis的第一个元素,因此您只能根据第一个元素的类型而不是procx递归调用lis。当前元素的类型。

那就是错误。

Scheme中lambda的强大功能来自于捕获其范围内所有变量的当前状态的能力。 inner-map的引用虽然没有传递给你的lambda,却是从lambda范围之外的$('#first').children('div').removeClass(); 函数范围内获取的。