我有这个代码删除列表的最后一个元素。如何更改此设置以删除设置的字词而不管其位置如何?

时间:2014-08-07 17:51:44

标签: scheme racket

#lang racket
(define (remove-last lst)
    (if (null? (cdr lst))
        '()
        (cons (car lst) (remove-last (cdr lst)))))

(remove-last '(Help Me Please))

然后打印出来:

(Help Me)

我该怎么改变?例如,如果我想删除me

2 个答案:

答案 0 :(得分:1)

像这样,例如:

(define (remove-words lst words)
  (cond 
    ((null? lst) 
     '())
    ((member (car lst) words) 
     (remove-words (cdr lst) words))
    (else 
     (cons (car lst) (remove-words (cdr lst) words)))))

然后

> (remove-words '(Help Me Please) '(Me Help Not))
'(Please)

您还可以使用集合的过程:

(define (remove-words lst words)
  (set-subtract lst words))

请注意,您在此处使用符号,而不是字符串。

答案 1 :(得分:1)

您也可以同时使用filter-notmember来解决问题:

(define (remove-words lst words)
  (filter-not (lambda (x) (member x words) lst))

如果你想减少匿名函数的冗长,最适合的工具是currycut(后者需要使用(require srfi/26))。

使用函数将其转换为接受一个参数的新函数,然后返回另一个接受一个参数的函数,然后再次接受,然后再次,依此类推,直到它具有调用原始函数所需的所有参数。 remove-words的curried版本将被称为((remove-words lst) words),您可以使用(curry remove-words)从我们当前的实现中获取它。这要求以从左到右的顺序提供参数,这对member不起作用。还有另一种形式curryr从右到左,但因为member采用可选的第三个参数,它将无效。

您可以使用cut(来自srfi 26),这样您就可以选择要锁定的函数的哪些参数以及您希望新函数接受哪些参数。 (cut member <> words)创建新功能(lambda (arg) (member arg words))(cut * <> <> 8)创建(lambda (arg1 arg2) (* arg1 arg2 8))。因此,remove-words看起来像是:

(require srfi/26)
(define (remove-words lst words)
  (filter-not (cut member <> words) lst))

虽然使用set-subtract仍然可能是最好的解决方案,因为你应该尽可能避免重新发明轮子(除非你试图更多地了解轮子)。尽管如此,掌握Racket提供的一般功能非常​​有用,可以让您的生活更轻松。