2012-03-22 81 views
15

任何人都有用于访问JavaScript对象的惯用clojurescript的任何文档(作为json返回,本质上是一个哈希)?用clojurescript自动访问json对象

我通过Ajax请求返回的JSON对象:

{ 
    list: [1,2,3,4,5], 
    blah: "vtha", 
    o: { answer: 42 } 
} 

我如何进入这些领域使用clojurescript?

我可以这样做:

(.-list data) 

但如何做,当我有嵌套值和对象这项工作?

(.-answer (.-o data)) 

上面看起来很笨拙,尤其是考虑到js语法:data.o.answer。

用clojurescript访问json对象的习惯用法是什么?

注:

我意识到,其实我可以指的是使用JS的语法,这是相当方便的实际元素。所以下面将正常工作:

(str data.o.answer) 
+1

我在你的实际设置假设,你会得到正确的JSON? – 2012-03-22 11:05:44

+0

是的,实际的JSON – 2012-03-24 23:05:50

+0

到目前为止,我认为答案是真的:没有这样做的惯用方式(还)。 – 2012-03-24 23:07:39

回答

10

首先,你提出的语法嵌套访问,那么:

ClojureScript:cljs.user> (def data 
    (JSON/parse "{\"list\": \"[1,2,3,4,5]\", \"blah\": \"vtha\", \"o\": {\"answer\": \"42\"}}")) 
#<[object Object]> 
ClojureScript:cljs.user> (.-answer (.-o data)) 
"42" 

可以使用线程宏...

ClojureScript:cljs.user> (-> data (.-o) (.-answer)) 
"42" 

或者..符号

ClojureScript:cljs.user> (.. data -o -answer) 
"42" 
+0

确实有效,即使使用线程宏,对我来说仍然显得笨重。 – 2012-03-24 23:08:46

+1

线程中的parens是多余的'( - > data。-o。-answer)' – noisesmith 2014-04-14 16:00:05

+1

@noisesmith这些天我宁愿使用''(.. data -o -answer)'',正如@ stephen-nelson - 我会更新答案 – sw1nn 2014-04-14 20:47:47

5

如果你处理任何数量的数据,我的JSON转换为Clojure的数据结构,然后使用普通的成语:

(let [my-json (js* "{ 
        list: [1,2,3,4,5], 
        blah: \"vtha\", 
        o: { answer: 42 } 
        }") 
     converted (js->clj my-json)] 

    (get-in converted ["list" 3]) ;; => 4 
    (-> converted "o" "answer") ;;=> 42 
) 

(注:请不要使用js*,如果你能帮助它;它不是成语,并可能走在ClojureScript的未来版本)

+0

我发现数据被转换成矢量而不是哈希,所以实际上更多的co,从比默认的js对象中提取数据更加复杂 – 2012-03-24 23:03:37

+0

实际上,转换的数据似乎以变​​化不可预知... obj地图或向量 – 2012-03-24 23:04:57

+0

这就像买整个杂货店只是为了得到橙子。浪费资源。 – 2015-10-09 01:10:41

16

你可能想皮亚杰:

(aget foo "list") 

皮亚杰不是可变参数还没有,但希望会很快 它现在是可变参数。 (aget data "o" "answer")会工作

+3

为了记录,现在它是可变的。 (年龄数据“o”“答案”)将起作用。 – 2013-02-28 15:20:02

+0

FWIW,大卫现在收回这个答案,并建议'(goog.object/get foo“list”)'。在刘家才的回答中可以看到更多。 – 2018-01-29 14:22:47

1

Clojurescript有..操作符是JavaScript的链接调用有用:

(.. data -o -answer) => data.o.answer => 42 
(aget (.. data -list) 1) => data.list[1] => 2 

您可以使用大多数经营者名单上排列得,例如

(into [] (.. data -list)) ; vector [1 2 3 4]