方案:从列表中删除某些内容并更新优先级

Scheme: removing something from a list and updating priorities

我正在尝试实现某种购物 list/queue 类型的功能。我遇到一些问题的函数是 removeByPriority。我想传递一个数字和一个要删除的项目列表。如果它不在列表中,那么只是 return 列表,但如果它在列表中,则将其删除,然后 return 更新优先级的列表。

例如,(removePriority 2 shopping-list) 会 return:

=> (("Apple" 3) ("Milk" 2) ("Eggs" 1))

我已经创建了一些有用的辅助函数,并且可以成功地检查某个优先级是否在列表中,但我被困在那里。

#lang scheme

(define shopping-list '( ("Apple" 4) ("Orange" 2)  ("Milk" 3) ("Eggs" 1)) )

(define name (lambda (m)
               (car m)
               ))

(define priority (lambda (m)
                   (car (cdr m))
                   ))

(define containsPriority
  (lambda (k lst)
    (cond
      ((null? lst)#f)
      ((equal? k (priority (car lst)))#t)
      (else (containsPriority k (cdr lst)))
      )
    )
  )

(removeByPriority k lst)

(define removeByPriority
  (lambda (k lst)
    (if((not(containsPriority k lst))lst)
       (equal? k (priority(car lst)))
           (else(removeByPriority k (cdr lst))(cons (car lst)))
        )
      )
    )

(removeByPriority 2 shopping-list)

您应该尽可能使用现有的程序,还有一些程序可以进一步简化。对于初学者来说,这些更简单并且等同于您写的内容:

(define name car)
(define priority cadr)

(define (containsPriority k lst)
  (cond ((null? lst) #f)
        ((equal? (priority (car lst)) k) #t)
        (else (containsPriority k (cdr lst)))))

这是有趣的部分。检查后,我们过滤我们不想要的值,然后我们映射结果列表,降低优先级:

(define (removeByPriority k lst)
  (if (not (containsPriority k lst))
      lst
      (map (lambda (pair)
             (list (name pair)
                   (if (< (priority pair) k)
                       (priority pair)
                       (sub1 (priority pair)))))
           (filter-not (lambda (pair)
                         (equal? (priority pair) k))
                       lst))))

它按要求工作:

(define shopping-list '(("Apple" 4) ("Orange" 2)  ("Milk" 3) ("Eggs" 1)))
(removeByPriority 2 shopping-list)
=> '(("Apple" 3) ("Milk" 2) ("Eggs" 1))