0

我在获取与哈希表中的键关联的值时遇到了麻烦,而且我对自己做错了什么感到完全困惑。我正在使用的代码如下所示:

(use-modules (curl))
(use-modules (json))

;; use curl to hit the site's api to get results of query as json:                                                                   
(define handle (curl-easy-init))
(curl-easy-setopt handle 'url
              "http://api.data.gov:80/regulations/v3/documents.json?api_key=mySecKey&countsOnly=0&encoded=1&dktid=EPA-HQ-OAR-2013-0602&dkt=R&cp=C&rpp=25&po=0")
(define s (curl-easy-perform handle))

;; parse the json in the string into guile scheme:                                                                                   
(define queryResults (json-string->scm s))

;; use this to see the keys and values in the resulting hash table:                                                                  
(define print-hash (lambda (my-hash)
                     (hash-for-each (lambda (key value)
                                      (format #t "~a => ~a~%" key value))
                                    my-hash)))

;; now let's take a look at the keys and values:                                                                                     
(print-hash queryResults)

;; now let's get the value associated with the documents key:                                                                        
(hashq-get-handle queryResults 'documents)

它依靠guile-curlguile-json与网络服务器对话并解析响应。在我跑步之前,事情似乎很简单。我可以在 json 中看到来自服务器的响应(很长,这里没有发布)和来自 Emacs 中的响应(使用 geiser 来查看)我可以看到:

scheme@(guile-user)> (hash-table? queryResults)
$25 = #t

所以我知道 queryResults 确实是一个哈希表。当我使用 print-hash 查看键和关联值时,我看到:

scheme@(guile-user)> (print-hash queryResults)
totalNumRecords => 23318
documents => (#<hash-table 2ad7c60 17/31> #<hash-table 2afdbc0 17/31> #<hash-table 2b0ab60 17/31> #<hash-table 2b0eb00 17/31> #<hash-table 2b10aa0 17/31> #<hash-table 2b13a40 17/31> #<hash-table 2b189e0 17/31> #<hash-table 2b1b980 17/31> #<hash-table 2b1e920 17/31> #<hash-table 2b228c0 17/31> #<hash-table 2b25860 17/31> #<hash-table 2b29800 17/31> #<hash-table 2b2d7a0 17/31> #<hash-table 2b30740 17/31> #<hash-table 2b336e0 17/31> #<hash-table 2b38680 17/31> #<hash-table 2b3b620 17/31> #<hash-table 2b3f5c0 17/31> #<hash-table 2b44560 17/31> #<hash-table 2b48500 17/31> #<hash-table 2b4c4a0 17/31> #<hash-table 2b50440 17/31> #<hash-table 2b533e0 17/31> #<hash-table 2b57380 17/31> #<hash-table 2b5c320 17/31>)

所以这很好,这是我所期望的。但是当我尝试使用 hashq-get-handle 来查看 totalNumRecords 或文档的值时,我得到:

scheme@(guile-user)> (hashq-get-handle queryResults 'totalNumRecords)
$24 = #f

scheme@(guile-user)> (hashq-get-handle queryResults 'documents)
$24 = #f

这似乎表明哈希表查询结果中不存在密钥。我已经用引号尝试了整晚,不带引号,使用 SRFI-69 哈希表实现(在此期间我发现了本机 guile 哈希表和 SRFI-69 哈希表之间的区别),并经历了guile 参考手册中的哈希表示例(它们都工作得很好)。我没主意了。

如果有人可以帮助我理解为什么我对 hashq-get-handle 的调用没有按预期进行,我将不胜感激。

更新:根据 guile-user 邮件列表中 ttn 的建议:

scheme@(guile-user)> (hash-get-handle queryResults 'totalNumRecords)
$27 = #f
scheme@(guile-user)> (hashv-get-handle queryResults 'totalNumRecords)
$28 = #f

所以看起来结果是一样的。没爱。

4

1 回答 1

0

这个关于 guile-user 邮件列表的讨论(来自 Thien-Thi Nguyen 和 Mark H Weaver)产生了这里总结的解决方案:

基于对 json 代码的快速浏览,我怀疑你想要这个:

(哈希获取句柄查询结果“文档”)

即将'hashq-get-handle' 更改为'hash-get-handle',并传递一个字符串作为键,而不是符号。

最终解决了:

scheme@(guile-user)> (hash-get-handle queryResults "documents")
$29 = ("documents" #<hash-table 297f820 17/31> #<hash-table 2982700
17/31> #<hash-table 29896a0 17/31> #<hash-table 298f640 17/31> #\
<hash-table 29915e0 17/31> #<hash-table 299d580 17/31> #<hash-table
29a1520 17/31> #<hash-table 29a34c0 17/31> #<hash-table 29a6460 \
17/31> #<hash-table 29f7400 17/31> #<hash-table 29fd3a0 17/31>
#<hash-table 2a08340 17/31> #<hash-table 2a1c2e0 17/31> #<hash-table \
2a4b280 17/31> #<hash-table 2a96220 17/31> #<hash-table 2aa31c0 17/31>
#<hash-table 2aa5160 17/31> #<hash-table 2aaa100 17/31> #<has\
h-table 2ab10a0 17/31> #<hash-table 2abb040 17/31> #<hash-table
2accfe0 17/31> #<hash-table 2acef80 17/31> #<hash-table 2ad1f20 17/3\
1> #<hash-table 2af1ec0 17/31> #<hash-table 2af4e60 17/31>)

马克提出的另一个建议很有道理:

如果在 'print-hash' 中使用 "~s" 而不是 "~a",则键是字符串还是符号将很清楚,因为字符串将在双引号内打印。

于 2014-12-08T01:22:42.800 回答