Предположим, у меня есть простая карта, example-map:

(def example-map {"a" "b" "c" "d"}) 

Я могу использовать clojure.data.json/write-str для JSON-ify этой карты как таковой:

(clojure.data.json/write-str example-map) =>
"{\"a\":\"b\",\"c\":\"d\"}"

Я хотел бы применить предикат ко всем ключам, чтобы определить, указан ли этот ключ в кавычках, даже если выходные данные неверны JSON.

Желаемая функция будет работать следующим образом:

(defn to-quote? [v] (= v "d"))

(fictional-write-str example-map :quote-rule to-quote?) =>
"{\"a\":\"b\",\"c\":d}"

Возможно, дополнительный :value-fn параметр clojure.data.json/write-json будет предлагать то, что я ' я описываю?

1
David Shaked 24 Апр 2017 в 19:23

2 ответа

Лучший ответ

write-str работает по протоколу JSONWriter, который вы можете расширить, скажем, clojure.lang.Symbol и сделать так, как вам нужно.

(ns reagenttest.main
    (:refer-clojure :exclude (read))
    (:require [clojure.data.json :as json]))

(defn- write-named [x out]
    (.print out (name x)))

(extend clojure.lang.Symbol json/JSONWriter {:-write write-named})

(prn (json/write-str {"a" 'd "b" "c" "e" :key}))

Шоу

"{\"a\":d,\"b\":\"c\",\"e\":\"key\"}"
1
akond 24 Апр 2017 в 16:46

Вы не должны использовать clojure.data.json, чтобы писать вещи, которые не являются json. Какой смысл? Соответствующие парсеры корректно откажутся разбирать ту чушь, которую ты пишешь. Вот почему это нелегко сделать, то есть в библиотеку не встроено ничего, что позволяло бы вам это делать. Вы можете обмануть, внедрив объекты со специальными типами, для которых вы реализуете JSONWriter, но опять же, это очень сильно не рекомендуется.

Почему ты хочешь сделать это? Существует, безусловно, более разумный способ решить вашу актуальную проблему; «Как получить библиотеку JSON для вывода неверного JSON» - неправильная отправная точка.

1
amalloy 24 Апр 2017 в 19:44
43593241