Lisp 过滤掉除数字以外的任何值

Lisp 过滤掉除数字以外的任何值,lisp,racket,Lisp,Racket,我试图想出一个程序,过滤掉除数字以外的任何值。例如: '(12(a)3)=>'(12(3)或'(12(a 10 11(b 2(c)))3)=>'(12(10 11(2())3) 这是我到目前为止所拥有的,但它并不真正起作用,因为它将非数字替换为空列表,而不是空列表: (define (filter-numbers lst) (if (null? lst) '() (if (list? lst) (cons (filter-nu

我试图想出一个程序,过滤掉除数字以外的任何值。例如:

'(12(a)3)=>'(12(3)
'(12(a 10 11(b 2(c)))3)=>'(12(10 11(2())3)

这是我到目前为止所拥有的,但它并不真正起作用,因为它将非数字替换为空列表,而不是空列表:

(define (filter-numbers lst)
  (if (null? lst)
      '()
      (if (list? lst)
          (cons
           (filter-numbers (car lst))
           (filter-numbers (cdr lst)))
          (if (number? lst)
              lst
              '())))
  )
该程序输出以下内容:

> (filter-numbers '(1 2 (a) 3))
'(1 2 (()) 3)

您需要检查子列表中的元素是否为数字,然后才能决定是否将其转换为输出。我认为如果我们稍微重新构造代码会更容易;还有一些提示:不要使用
list?
,更喜欢
pair?
,因为它速度更快(与
list?
不同,它不需要遍历整个列表)。并且更喜欢
cond
而不是嵌套
if
s,您的代码将更易于阅读。这就是我的意思:

(define (filter-numbers lst)
  (cond ((null? lst) lst)
        ((not (pair? (car lst)))
         ; check the element while still in a list, if we wait
         ; until we reach an atom it's too late to filter it out
         (if (number? (car lst))
             ; either add the element to the output or skip it
             (cons (car lst) (filter-numbers (cdr lst)))
             (filter-numbers (cdr lst))))
        (else (cons
               (filter-numbers (car lst))
               (filter-numbers (cdr lst))))))
它按预期工作:

(filter-numbers '(1 2 (a) 3))
=> (1 2 () 3)
(filter-numbers '(1 2 (a 10 11 (b 2 (c))) 3))
=> '(1 2 (10 11 (2 ())) 3)

您需要先检查子列表中的元素是否为数字,然后再决定是否将其转换为输出。我认为如果我们稍微重新构造代码会更容易;还有一些提示:不要使用
list?
,更喜欢
pair?
,因为它速度更快(与
list?
不同,它不需要遍历整个列表)。并且更喜欢
cond
而不是嵌套
if
s,您的代码将更易于阅读。这就是我的意思:

(define (filter-numbers lst)
  (cond ((null? lst) lst)
        ((not (pair? (car lst)))
         ; check the element while still in a list, if we wait
         ; until we reach an atom it's too late to filter it out
         (if (number? (car lst))
             ; either add the element to the output or skip it
             (cons (car lst) (filter-numbers (cdr lst)))
             (filter-numbers (cdr lst))))
        (else (cons
               (filter-numbers (car lst))
               (filter-numbers (cdr lst))))))
它按预期工作:

(filter-numbers '(1 2 (a) 3))
=> (1 2 () 3)
(filter-numbers '(1 2 (a 10 11 (b 2 (c))) 3))
=> '(1 2 (10 11 (2 ())) 3)

非常感谢你的帮助!这太棒了:)非常感谢你的帮助!这太棒了:)