ウェブ技術 デジタルトランスフォーメーション技術 人工知能技術 自然言語処理技術 セマンティックウェブ技術 深層学習技術 オンライン学習&強化学習技術 チャットボットと質疑応答技術 ユーザーインターフェース技術 知識情報処理技術 推論技術 Clojure プログラミング
前回は、Clojureの特徴であるREPLとimmutableなデータについて述べた。今回はデータ構造について述べる。
JavaScriptのデータでは、文字列(string)、数値(Number)、ブール(Boolean)等の単一のデータであるプリミティブ型と、それらを複数組み合わせて[]で囲んだ配列や、さらに名前と値のペアの集合を({})で囲んだオブジェクト型がある。
Pythonの場合はリスト(list)型として[]で囲んでカンマ(,)で区切ったデータや、タプル(tuple)型として()で囲んでカンマ(,)で区切ったデータ、辞書(dict)型として{}で囲んでキー値と代入値をコロン(:)で挟んでカンマ(,)で区切ったデータがある。(list型とtuple型の違いはimmutableかどうか)
これに対してClojureの場合はデータ(値)を複合的に集めた(collect)ものをコレクション(Collection)と呼び、コレクションはベクター、リスト、セット、マップの4種類の型を持っている。
ベクターは[]で囲まれたデータで、記述されている順序は固定でインデックス数(何番目に並んでいるか)を指定することでデータにアクセスできる。「(get [“abc” false 99] 2)→99」
リストは()で囲まれたデータで、シーケンシャル(sequential)な連結リストを表し、最初の要素は関数として評価される。(コードもデータの一種)
セットは数学での集合のデータを表し、データの順序は固定されておらず、データの重複もない。集合を扱う関数clojure.set/difference (集合間の差分を取る)、clojure.set/intersection(集合間の共通を取る)、clojure.set/union(集合のorを取る)等を適用することができる。
マップはキーと値のペアを{}で囲んだデータで{“Fred” 1400, “Bob” 1240, “Angela” 1024}と表したり、{:Fred 1400 :Bob 1240 :Angela 1024}とも表せる。内部のデータにアクセスするには例えばget関数で(get {“Fred” 1400, “Bob” 1240, “Angela” 1024} “Angela”)→1024と使うことができる。
これらを組み合わせたClojure特有のデータ構造としてedn(Extensible Data Notation)がある。JSONやYAMLのようなデータ表記法の一種で、様々なデータを表すことのできる拡張性の高いデータ構造だ。leiningenのコンフィギュレーションファイルやwebアプリ系で使われるintegrantの設定ファイル、あるいは独自のデータベースであるDATOMICでのデータフォーマットとして使われ、Clojureを使う上では切っても切れないものとなっている。
具体的なデータ表記の例として例えば以下のようなxmlデータが
<binding name='s'>
<uri>http://learningsparql.com/ns/data#CA</uri>
</binding>
<binding name='p'>
<uri>http://www.w3.org/2000/01/rdf-schema#label</uri>
</binding>
<binding name='o'>
<literal>California</literal>
</binding>
JSONでは以下のように表され
"binding": [
{
"@name": "s",
"uri": "http://learningsparql.com/ns/data#CA"
},
{
"@name": "p",
"uri": "http://www.w3.org/2000/01/rdf-schema#label"
},
{
"@name": "o",
"literal": "California"
}
]
ednでは以下のようになる。
[{:tag :binding,
:attrs {:name "s"},
:content
[{:tag :uri,
:attrs nil,
:content ["http://learningsparql.com/ns/data#CA"]}]}
{:tag :binding,
:attrs {:name "p"},
:content
[{:tag :uri,
:attrs nil,
:content ["http://www.w3.org/2000/01/rdf-schema#label"]}]}
{:tag :binding,
:attrs {:name "o"},
:content
[{:tag :literal, :attrs nil, :content ["California"]}]}]}
人の目でみるにはとっつきにくいデータフォーマットだが、clojure.zip関数や、mapデータからのデータ抽出に使うget関数を用いることで容易にデータにアクセスすることができる形となる。
次回はちょっと寄り道して、以前読んだマイクロ原子力発電の記事について述べてみたい。
コメント
[…] ピンバック: Clojureについて(4) – Deus Ex Machina […]
[…] Clojureを始めよう(4) 各種データ構造 […]