首页 > 解决方案 > 在球拍中,我如何返回一个列表,其中包含两个不同字典中出现的所有键

问题描述

我基本上只是想找到两个不同字典中存在的键并将这些键输入到列表中。

到目前为止,这是我的代码

(define-struct asc (key val))
;; An Asc is a (make-asc Any Any)
;; a Dict (dictionary) is a (listof Asc)


(define (common-keys D1 D2)
  (cond
    [(or (empty? D1) (empty? D2)) '()]
    [(equal?  (asc-val (first D1)) (asc-val (first D2)))
 (cons (asc-key (first D1)))]
    [ else (cons (asc-key (first D1 (common-keys (rest D1) (rest D2)))))])) 

该代码显然不起作用。我对这个问题的思考过程是首先检查任一字典是否为空,然后查看两个字典中的第一个值是否相等,如果相等,则构建一个列表。我现在需要添加一个部分,然后在其余的字典中进行迭代,以查看其他键是否相等。我不确定如何做到这一点,我仍然没有同时处理多个列表的经验,所以一次处理多个字典对我来说有点棘手。

这是一个测试用例示例

(check-expect (common-keys
               (list (make-asc 1 "one") (make-asc 15 "fifteen"))
               (list (make-asc 15 "fifteen") (make-asc 8 "eight")))
              (list 15)) 

因为 15 是两个字典中唯一的值,所以函数应该只返回(列表 15)

标签: listdictionaryschemeracket

解决方案


您的方法的问题是您假设两个字典中的元素位于相同的位置,但情况并非总是如此。您必须检查一个字典中的每个键与另一个字典中的所有其他键,如果您为此构建一个帮助程序会更简单。

可是等等!如果我们从高阶程序的角度考虑,会有一个更简单的解决方案。我们只需要映射每个字典的键,然后与公共元素相交。做起来比说的容易:

(define (common-keys D1 D2)
  (set-intersect
   (map asc-key D1)
   (map asc-key D2)))

它按预期工作:

(common-keys
 (list (make-asc 1 "one") (make-asc 15 "fifteen"))
 (list (make-asc 15 "fifteen") (make-asc 8 "eight")))
=> '(15)

推荐阅读