プログラミング技術 ICT技術 Javascriptによるフロントエンド開発 ウェブ技術 Clojureと関数プログラミング デジタルトランスフォーメーション
Clojureでデータ処理を行う際に、よく使うのがMapデータへのアクセスだ。たとえばpostgresqlデータベース等の出力あるいはCSVのデータのマップとして以下のようなものがあるとする。
(def output-text [{:id 1 :text "aaa" :tag true}
{ :id 2 :text "bbb" :tag false}
{ :id 3 :text "ccc" :tag true}
{ :id 4 :text "ddd" :tag true}
{ :id 5 :text "eee" :tag false}])
この中から、任意の:textのデータを抽出したい時は
(defn output-data [n]
(->> output-text
(filter #(= (:text %) n))
first))
とすると
(output-data "ccc")
-> {:id 3 :text "ccc" :tag true}
のように抽出できる。「=」関数の代わりに「re-find」関数を使うと、以下のように簡単な全文検索のようなことも出来る。
(defn search-data [n]
(filter #(re-find (re-pattern n) (:text %)) output-text))
ここで、rdf storeの出力のようなもう少し複雑にネストしたmap構造(例えば以下のようなxmlから生成されたもの)の場合は
<root>
<records>
<record id="1">record01</record>
<record id="2">record02</record>
</records>
<record id="3">record03</record>
</root>
clojure.data.zipを使って以下のようにleiningenのdependencyを設定して
[org.clojure/data.zip "1.0.0"]
以下のような形でデータを抽出する。
(use 'clojure.data.zip.xml)
(require ['clojure.xml :as 'xml])
(require ['clojure.zip :as 'zip])
(xml-> (zip/xml-zip (xml/parse "in.xml")) :records :record text)
; -> ("record01" "record02")
(xml-> (zip/xml-zip (xml/parse "in.xml")) :record text)
; -> ("record03")
(xml-> (zip/xml-zip (xml/parse "in.xml")) :record (attr :id))
; -> ("3")
複雑な構造のデータの場合は、SAPRQL等のクエリで直接DBからAPI経由で加工済みのデータを取る方がより簡易にできると思う。
コメント
[…] Mapからのデータの抽出 […]