ハッシュの要素をランダムに抽出する


Tags: ハッシュ, 【募集中】

ハッシュの要素をランダムに抽出する

Common Lispのハッシュテーブルは順番付きハッシュテーブルではありません。値に無頓着に何か要素が一つ欲しいということであれば、with-hash-table-iterator等で先頭の一つを取り出せば良いでしょう。
要素の中から都度ランダムに取り出したいということならば、下記の様になるでしょう。

(defun hash-table-choice (hash-table)
  (block nil
    (let ((pos (random (hash-table-count hash-table)))
          (cnt 0))
      (maphash (lambda (k v)
                 (when (= pos cnt) (return (values k v)))
                 (incf cnt))
               hash-table))))
;; loopで
(defun hash-table-choice (hash-table)
  (loop :with pos := (random (hash-table-count hash-table))
        :for k :being :each :hash-key :using (:hash-value v) :of hash-table
        :for idx :from 0
        :when (= idx pos) :return (values k v)))

実行

(hash-table-choice 
 (alexandria:alist-hash-table (pairlis '(1 2 3 4 5) '(a b c d e))))
;=>  5
;    E