简体   繁体   English

在Racket中,如何返回包含两个不同字典中出现的所有键的列表

[英]In Racket how do I return a list that contains all the keys which occur in two different dictionaries

I am basically just trying to find keys that exist in two different dictionaries and input those keys into a list. 我基本上只是想找到存在于两个不同字典中的密钥并将这些密钥输入到列表中。

Here is my code so far 到目前为止,这是我的代码

(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)))))])) 

The code obviously doesn't work. 代码显然不起作用。 My thought process for this question was to first to check to see if either dictionary is empty and then see if the first values in both dictionaries are equal, if they are, then I construct a list. 我对这个问题的思考过程是首先检查一个字典是否为空,然后查看两个字典中的第一个值是否相等,如果是,则构造一个列表。 I now need to add a section where it then iterates throughout the rest of the dictionaries to see whether the other keys are equal. 我现在需要添加一个部分,然后在其余的字典中迭代以查看其他键是否相等。 I am unsure how to do this, I'm still inexperienced working with many lists at once so working with multiple dictionaries at once is a bit tricky for me. 我不确定如何做到这一点,我仍然缺乏经验,同时处理多个列表因此,同时使用多个词典对我来说有点棘手。

This is a test case example 这是一个测试用例

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

since 15 is the only value in the two dictionaries the function should just return (list 15) 因为15是两个字典中唯一的值,函数应该返回(列表15)

The problem with your approach is that you're assuming that the elements are on the same positions in both dictionaries, and that's not always the case. 你的方法的问题在于你假设元素在两个字典中都处于相同的位置,并且情况并非总是如此。 You'd have to check every key in one dictionary against all the other keys in the other dictionary, it'll be simpler if you build a helper procedure for this. 您必须检查一个字典中的每个键与另一个字典中的所有其他键 ,如果您为此构建一个帮助程序,它将更简单。

But wait! 可是等等! there's an easier solution if we think in terms of higher-order procedures. 如果我们考虑更高阶的程序,那么这是一个更容易的解决方案。 We just need to map over the keys of each dictionary, and then intersect the common elements. 我们只需要映射每个字典的键,然后公共元素相交 Easier done than said: 比说的更简单:

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

It works as expected: 它按预期工作:

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

Longer example (just for educational purposes) with trail-recursive list-intersect. 更长的示例(仅用于教育目的)与trail-recursive list-intersect。

Just to show you how to get it done with your original approach. 只是为了向您展示如何使用您的原始方法完成它。

You have to first sort the list. 您必须先对列表进行排序。 And then go through both lists in parallel comparing the first elements of both lists. 然后并行浏览两个列表,比较两个列表的第一个元素。 If they are equal, you collect them in the accumulator ( acc ). 如果它们相等,则在累加器( acc )中收集它们。 If not eliminate the smaller first element and apply list-intersect on the reduced and the not-reduced list ... until at least one of the lists or both are empty. 如果不消除较小的第一个元素并在简化列表和未缩减列表上应用list-intersect ...直到至少一个列表或两者都为空。

You need to specify therefore two test-functions: 因此,您需要指定两个测试函数:

  • test-equal for equality test of the keys and test-equal键的相等测试和
  • test-less for testing whether one key is smaller than the other. test-less用于测试一个密钥是否小于另一个密钥。
(define-struct asc (key val))

(define (list-intersect lst1 lst2 (acc '()) #:test-equal (test-equal =) #:test-less (test-less <))
  (let ((lst1 (sort lst1 test-less))
        (lst2 (sort lst2 test-less)))
    (cond ((or (empty? lst1) (empty? lst2)) (reverse acc))
          ((test-equal (car lst1) (car lst2)) 
           (list-intersect (cdr lst1) (cdr lst2) (cons (car lst1) acc)))
          ((test-less (car lst1) (car lst2))
           (list-intersect (cdr lst1) lst2 acc))
          (else
           (list-intersect lst1 (cdr lst2) acc)))))

(define (common-keys D1 D2 #:test-equal (test-equal =) #:test-less (test-less <))
  (list-intersect (map asc-key D1) (map asc-key D2) #:test-equal test-equal #:test-less test-less))
(common-keys (list (make-asc 1 "one") (make-asc 15 "fifteen"))
             (list (make-asc 15 "fifteen") (make-asc 8 "eight")))
;; '(15)

Improved by @Sylwester (using only test-less ) 由@Sylwester改进(仅使用无test-less

(define (list-intersect lst1 lst2 (acc '()) #:test-less (test-less <))
  (let ((lst1 (sort lst1 test-less))
        (lst2 (sort lst2 test-less)))
    (cond ((or (empty? lst1) (empty? lst2)) (reverse acc))
          ((test-less (car lst1) (car lst2))
           (list-intersect (cdr lst1) lst2 acc))
          ((test-less (car lst2) (car lst1))
           (list-intersect lst1 (cdr lst2) acc))
          (else
           (list-intersect (cdr lst1) (cdr lst2) (cons (car lst1) acc))))))

(define (common-keys D1 D2 #:test-less (test-less <))
  (list-intersect (map asc-key D1) (map asc-key D2) #:test-less test-less))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从关联列表中获取密钥? 方案/球拍 - How do I get the keys from an association list? scheme/ racket 如何在字典列表中向字典添加键? - How do I add keys to a dictionary in a list of dictionaries? 如何使用 for 循环从存储在列表中的所有字典中的键返回值? - How do I use a for loop to return values from a key that features in all the dictionaries stored in a list? 如何对具有不同键的嵌套字典列表进行排序 - How to sort a list of nested dictionaries with different keys 如何从字典列表中删除或消除包含一个列表值的所有字典? - How to remove or eliminate all dictionary which contains one list value from a list of dictionaries? 如何向列表中的字典添加值? - How do I add values to dictionaries which is in a list? 检查两个键是否在词典列表中具有不同的值 - check if two keys have different values in a list of dictionaries 连接具有相同值和不同键的两个字典列表 - Joining Two List Of Dictionaries With Same Values And Different Keys 如何遍历嵌套字典并使用包含其他键之一的值的列表返回特定键值对 - How to loop through nested dictionaries and return a specific key value pair using a list that contains values of one of the other keys 希望返回所有可能的两个骰子。 返回值是一个包含元组的列表 - Looking to return all possible rolls of two dice. The return value is a list which contains tuples
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM