2012-03-22 82 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]