Clojureを始めよう(3)データ構造について

ウェブ技術 デジタルトランスフォーメーション技術 人工知能技術 自然言語処理技術 セマンティックウェブ技術 深層学習技術 オンライン学習&強化学習技術 チャットボットと質疑応答技術 ユーザーインターフェース技術 知識情報処理技術 推論技術  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関数を用いることで容易にデータにアクセスすることができる形となる。

次回はちょっと寄り道して、以前読んだマイクロ原子力発電の記事について述べてみたい。

コメント

  1. […] ピンバック: Clojureについて(4) – Deus Ex Machina […]

  2. […] Clojureを始めよう(4) 各種データ構造 […]

タイトルとURLをコピーしました