从数字创建关键字

时间:2016-08-28 14:19:21

标签: clojure clojurescript hoplon

TL;博士

如何从ClojureScript中的数字派生关键字:

(keyword 22)
;;=> :22 but in fact returns nil.

背景

在我的ClojureScript / Hoplon应用程序中,我通过cljs-http发出HTTP请求。我收到的部分回复如下:

{:companies
  {:22 {:description ... } ; A company.
   :64 {:description ... }
   ...                    }
{:offers
  [{:description ... } ; An offer.
   {:description ... }
   ...                ]

:offers后面的向量中的每个商品都有:companyId代表:companies中的密钥。我收到回复后,reset!一个cell(类似于原子)query

现在,我想迭代每个商品并调用一个创建相应HTML的函数offer-tpl。为此,offer-tpl需要提供本身以及相关公司:

(for [offer (:offers @query)]
  (offer-tpl offer (get-in @query [:companies (keyword (:companyId offer))]))))))

尽管事实上这肯定可以做得更优雅(建议非常赞赏),get-in不起作用。 (:companyId offer)会返回一个数字(例如22),但(keyword (:companyId offer))会返回nil。调用(keyword (str (:companyId offer)))可以解决问题,但是没有其他方法可以做到这一点吗?

1 个答案:

答案 0 :(得分:8)

(keyword "22")(keyword (str 22))返回:22

您获得:22的原因可能是因为JSON翻译的keywordize-keys选项。例如:

cljs-http默认为jasonp的keywordize-keys: https://github.com/r0man/cljs-http/blob/1fb899d3f9c5728521786432b5f6c36d1d7a1452/src/cljs_http/core.cljs#L115 但是你可以(并且应该)传入一个标志来禁用关键字。

并非JSON中的所有键都适用于Clojure关键字。例如,JSON密钥中的空格有效,但不在Clojure中。

请注意,数字关键字可能不正确。 https://clojuredocs.org/clojure.core/keyword#example-542692cec026201cdc326d70 似乎已经从当前的Clojure网站上删除了警告,所以也许这意味着什么,但我不确定是什么。

http://clojure.org/reference/reader目前声明

  

关键字 - 关键字就像符号一样,除了:它们可以而且必须开始   用冒号,例如:弗雷德。他们不能包含'。或命名类。   与符号一样,它们可以包含命名空间:person / name关键字   从两个冒号开始在当前命名空间中解析:In   用户名空间,:: rect读作:user / rect

那个

  

符号以非数字字符开头,可以包含   字母数字。

关键字的这一定义排除了:22:with spaces

关键字函数返回无效输入的结果,但这不是认可,这只是因为检查错误输入将是Clojure核心部分的性能开销。

简而言之,并非所有JSON密钥都转换为关键字,因此除非您知道密钥空间和/或这样做提供了一些便利,否则应该避免使用keywordize-keys