4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

EmacsAdvent Calendar 2017

Day 3

連想リストのUPSERT

Last updated at Posted at 2017-12-02

UPSERTとは

データが存在するかどうかをチェックし、存在すれば更新、存在しなければ挿入を行うという処理は、よく行われます。

リレーショナルデータベース(RDBMS)上のSQL言語では、こうした処理を一文で行うためのコマンドを俗にUPSERTと呼び、長年にわたって実装や標準化が望まれていました。UPSERTは結局、SQL:2003にてMERGE文という形で標準化され、Oracle DatabaseやMicrosoft SQL Server、IBM DB2などの主要なRDBMS製品で実装されるようになっています。

Emacs Lisp連想リストのUPSERT

UPSERTは、Emacsで連想リストを扱う場合でも使いたい場合があります。例えば、フレームの形状を設定する連想リストdefault-frame-alistでEmacsのフレームの幅を100に設定する場合です。
default-frame-alistwidthがすでに設定されている場合はwidthの値を100に更新し、設定されていない場合は(width . 100)default-frame-alistに挿入するという処理になります。しかし、こうした処理をいちいちinit.elなどの初期化ファイルに記述していったのでは、面倒ですし、初期化ファイルのメンテナンスもたいへんになります。そこで作ったのがEmacs Lispで連想リストのUPSERTを実現する次の関数update-or-add-alistです。

(defun update-or-add-alist (alist-var key value)
  "If KEY in ALIST, update VALUE of the KEY.
Unless, cons cell (KEY . VALUE) is added."
  (let (acell (alst (symbol-value alist-var)))
   (if (setq acell (assoc key alst))
       (unless (equal (cdr acell) value)
         (setcdr acell value))
     (set alist-var (push (cons key value) alst)))
   alst))

この関数を定義したあと、default-frame-alistでフレームの幅を100に設定するには、次のようにします。

(update-or-add-alist 'default-frame-alist 'width 100)

よければ、お試しください

おまけ

実は、こういう関数はすでに標準で存在しているはずなのに…といろいろ調べたのですがついに見つけられず、自分で実装したという経緯があります。心当たりの方がいれば、教えてください^^

4
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?