【问题标题】:How can I filter null values from this list?如何从此列表中过滤空值?
【发布时间】:2015-08-09 23:06:33
【问题描述】:

我有以下过程来创建列表中的所有素数对:

(define (prime-pairs lst)
  (define (split lst pos)
    (list (drop-right lst pos) (take-right lst pos)))
  (define (prime-pairs-iter n acc)
    (cond ((= n 0) (filter (lambda (e) (not (null? e))) acc))
          (else (prime-pairs-iter (- n 1) 
                                  (let ((s (split lst n)))
                                    (if (and (prime? (list->number (car s)))
                                             (prime? (list->number (cadr s))))
                                        (append s acc)
                                        acc))))))
  (prime-pairs-iter (- (length lst) 1) '()))

(完整代码:https://gist.github.com/anonymous/b8cfcb0bf021be9ef9c8

我想要prime-pairs 做的是创建一个包含两个素数的lst 中每一对的列表。这些数字以列表格式表示,如下所示:11 将是'(1 1)

不幸的是,当我运行此代码时,(filter (lambda (e) (not (null? e))) acc)) 似乎没有从最终结果中删除 '(),我最终得到了一长串空值和所需对的列表。

如果我使用(filter null? acc)),则会保留一个空值列表。所以反过来(过滤掉实际值)确实有效。

如何过滤掉返回列表的空值?

【问题讨论】:

  • 你能举例说明这种行为吗?
  • @ScottHunter 是的,下载 OP 发布的 Gist,并在 DrRacket 实例中运行。

标签: scheme lisp


【解决方案1】:

目前,您的 prime-pairs 函数始终返回一个值:空列表或素数对。使用map,没有办法避免空列表,不对map的结果做进一步过滤。

另一种方法是返回结果的列表,并使用append-map 而不是map。更改您的 prime-pairs 以返回一个空列表或 一个包含您的素数对的单例列表;这模拟返回零或一个值,而不是总是一个值。像这样:

(cond ((zero? n) (if (null? acc)
                     '()
                     (list acc)))
      ...)

现在,使用append-map

(append-map prime-pairs primes-list-split)

你应该得到你想要的结果。 (完整代码见my forked gist。)

【讨论】:

  • 起初我不明白为什么在你的回答中append-map 确实过滤掉了空值,而map 没有。原来append-mapmap 之间的区别在于append-map 使用append,而map 使用cons 将应用程序的结果连接到元素(source)。将 null 附加到列表会导致列表,将 null 附加到列表会导致列表加上 null。这就解释了为什么附加会导致过滤掉空值的结果。感谢您的帮助!
  • 我在使用该方法时遇到了其他问题。我创建了一个新问题:stackoverflow.com/questions/31998531/…
猜你喜欢
  • 2017-10-13
  • 2018-04-23
  • 2017-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-08
  • 2018-03-24
相关资源
最近更新 更多