ハッシュテーブル - Alexandria

概要

このページではCommon Lispの汎用ユーティリティであるAlexandriaの「ハッシュテーブル」に関するオペレータを紹介します。

ハッシュテーブルはANSI Common Lispの標準仕様では第18章に定められているので、そちらも参照してください。

なお、このページでは以下の状態でハッシュテーブルを作成済みとしてサンプルを紹介します。
;; ASDFによりAlexandriaをロード
(asdf:load-system :alexandria)

;; ハッシュテーブルの生成
(defparameter *url* (make-hash-table))

;; データの登録
(setf (gethash 'google *url*) "https://www.google.co.jp/")
(setf (gethash 'yahoo *url*) "https://www.yahoo.co.jp/")
(setf (gethash 'my-site *url*) "http://lisp.satoshiweb.net/")

ensure-gethashマクロ: 拡張版gethash

ANSI Common Lispの標準ではgethashアクセッサが定められており、ハッシュテーブルの中からkeyを手掛かりにvalueを見つけることができます。このアクセッサの返り値は多値で、2つ目の返り値がpresent-p、すなわちkeyを持つデータがあったかどうかを示します。標準仕様入門の第18章「ハッシュテーブル」では独自のgethash*関数を定義し、対応するデータがない場合にコンディションシステムを発動させ、エラーを通知するようにしたサンプルを紹介しています。

Alexandriaのensure-gethashマクロはまた別の拡張であり、対応するデータがない場合には値を登録することができます。
;; nikkei というkeyを持つデータは存在しないが、
;; ensure-gethashなら第3引数を指定して登録できる
(alexandria:ensure-gethash 'nikkei *url* "https://www.nikkei.com/")
; => "https://www.nikkei.com/" ;
;    NIL

;; たしかに登録されている
(gethash 'nikkei *url*)
; => "https://www.nikkei.com/" ;
;    T

第3引数はオプショナルなので、省略した場合はnilが使われます。もちろん、対応するデータがある場合は上書きせず、そのデータ(keyに対応するvalue)を取得するだけです。

copy-hash-table関数: ハッシュテーブルのコピー

Alexandriaのcopy-hash-table関数はハッシュテーブルのコピーを行います。
(alexandria:copy-hash-table *url*)
; => #S(HASH-TABLE :TEST FASTHASH-EQL (GOOGLE . "https://www.google.co.jp/")
;       (YAHOO . "https://www.yahoo.co.jp/")
;       (MY-SITE . "http://lisp.satoshiweb.net/"))

maphash-keys関数: key専用のmaphash関数

ANSI Common Lisp標準仕様ではmaphash関数が定められているので、高階関数を用いたハッシュテーブルの繰り返し処理を行うことができます。しかし、maphash関数はkeyvalueを共に引数として取る関数のみを対象にしているので、どちらか片方だけを使いたい場合はdeclareシンボルでignoreする必要があります。

Alexandriaのmaphash-keys関数とmaphash-values関数はそのようなニーズに対応するためのもので、単純に使わない方をignoreした状態で定義されています。
(alexandria:maphash-keys #'(lambda (v) (print v)) *url*)
; 
; MY-SITE 
; YAHOO 
; GOOGLE 
; => NIL

(alexandria:maphash-values #'(lambda (v) (print v)) *url*)
; 
; "http://lisp.satoshiweb.net/" 
; "https://www.yahoo.co.jp/" 
; "https://www.google.co.jp/" 
; => NIL

maphash-values関数: value専用のmaphash関数

前節のmaphash-keys関数の説明を参照してください。

hash-table-keys関数: ハッシュテーブルのkeyを取得

節のタイトルの通り、ハッシュテーブルのkeyを取得してリストにして返します。また、hash-table-valuesはハッシュテーブルのvalueを取得してリストに返します。
(alexandria:hash-table-keys *url*)
; => (GOOGLE YAHOO MY-SITE)

(alexandria:hash-table-values *url*)
; => ("https://www.google.co.jp/" "https://www.yahoo.co.jp/"
;     "http://lisp.satoshiweb.net/")

hash-table-values関数: ハッシュテーブルのvalueを取得

前節のhash-table-keys関数の説明を参照してください。

ハッシュテーブルと連想・属性リストの相互変換

keyとvalueでデータを保存する構造はハッシュテーブルだけでなく、連想リストや属性リストなども同じです。連想リストとはコンスの形でkeyとvalueを保持する構造で、属性リストとはkeyとvalueが交互に現れるリストとして保持する構造です。

連想リストと属性リストについては第14章「リスト」を参照してください。

Alexandriaにはハッシュテーブルと連想・属性リストを相互に変換する関数が用意されています。

Function: hash-table-alist
ハッシュテーブルを連想リストに変換します。
Function: hash-table-plist
ハッシュテーブルを属性リストに変換します。
Function: alist-hash-table
連想リストをハッシュテーブルに変換します。
Function: plist-hash-table
属性リストをハッシュテーブルに変換します。
以下が変換のサンプルです。

(alexandria:hash-table-alist *url*)
; => ((GOOGLE . "https://www.google.co.jp/") (YAHOO . "https://www.yahoo.co.jp/")
;     (MY-SITE . "http://lisp.satoshiweb.net/"))

(alexandria:hash-table-plist *url*)
; => (GOOGLE "https://www.google.co.jp/" YAHOO "https://www.yahoo.co.jp/"
;     MY-SITE "http://lisp.satoshiweb.net/")

0 件のコメント :

コメントを投稿