2

ClojureREPLでdefrecordを作成しました。

user=> (defrecord Data [column1 column2 column3])
user.Data

.jsonファイルを読み込んで、このレコードへのデータの追加を自動化するにはどうすればよいですか?defrecordの各列は、jsonデータのキーに正確に対応しています。ファイルに単一のレコードが含まれている場合、次のようになります。

[
  {
    "column1" : "value1"
    "column2" : "value2"
    "column3" : "value3"
  }
]

しかし、ファイルにはそのようなレコードが何千もあります。

私はこのようにファイルの内容を丸呑みすることができます:

(json/read-json (slurp "path/to/file.json")))

lein replread-json関数の依存関係は、コマンドラインから実行しているディレクトリにあるproject.cljファイルに追加されます:dependencies [org.clojure/data.json "0.2.1"]

Clojure関数を使用してレコードの値を検索できるようにしたいのですが、検索関数に渡す値は、単一のレコードのcolumn1とcolumn2の値の間にあります(つまり、nth-record.column1)。 .value <= query <= nth-record.column2.value)。一致するレコードを見つけたら、同じレコード内の別の列の値(nth-record.column3.value)を返します。列1と2の値は一意であり、重複しない値の範囲を表します。column3の値は一意ではありません。

これはかなり些細な作業のように思えますが、Clojureのドキュメントやオンラインで見つけた例を使用してそれを行う方法を理解することはできません。レコードを検索して同じレコード内の関連フィールドの値を返すことができる限り、レコードがClojureの内部にどのように格納されているかは私には関係ありません。

4

2 に答える 2

11

data.jsonパッケージの使用:

(require '[clojure.data.json :as json])

値をメモリに読み込みます。

(def all-records (json/read-str (slurp "path/to/file.json")
                :key-fn keyword))
;; ==> [ { :column1 "value1", :column2 "value2", :column3 "value3" }, ...]

一致するレコードを検索します。

(def query "some-value")
(def matching (filter #(and (< (:column1 %) query) (< query (:column2 %))) all-records))

column3を取得します。

(map :column3 matching)

それをすべて一緒に収集する(そしてそれをより柔軟にする):

(defn find-matching [select-fn result-fn records]
   (map result-fn (filter select-fn records)))

(defn select-within [rec query]
  (and (< (:column1 rec) query) (< query (:column2 rec))))

(find-matching #(select-within % "some-value") :column3 all-records)
于 2013-03-27T15:07:35.303 に答える
1
  1. おそらくスピードのためにチェシャーを使うべきです。
  2. クエリが十分に複雑になる場合は、luceneを検討してください。clojureには優れたラッパーがあります。

私が知る限り、レコードはポリモーフィズムのようにレコードを特別なものにする機能を使用していないので、レコードはマップよりも何らかの形でこれに適していると考えていると思います。チェシャーがレコードを吐き出す方法があるかもしれませんが、私は気にしません。

于 2013-03-27T13:37:19.867 に答える