--- title: リストをフィルターする関数 author: kazu634 date: 2010-05-15 wordtwit_post_info: - 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:5257;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}' categories: - gauche - Lisp ---
2010-05-11 – 武蔵の日記で予告していたリストをフィルタリングする関数を作成してみました:
(define (filter-list-by key-fn value cmp xs) (map cdr (filter (lambda (x) (if (cmp (car x) value) #t #f)) (map (lambda (x) (cons (key-fn x) x)) xs))))
;; 前提になるライブラリを読み込む gosh> (use srfi-1) #<undef> gosh> (use sxml.ssax) #<undef> gosh> (use sxml.sxpath) #<undef> ;; 前提になる get-value-from-sxml を定義 gosh> (define (get-value-from-sxml sxpath sxml) ((if-car-sxpath `(// ,sxpath *text*)) sxml)) get-value-from-sxml ;; type が photo のものを抽出する gosh> (let ((sxml '((post (|@| (type "quote") (id "547214365"))) (post (|@| (type "quote") (id "1234567890"))) (post (|@| (type "photo") (id "foo")))))) (filter-list-by (lambda (x) (get-value-from-sxml 'type x)) "photo" equal? sxml)) ((post (|@| (type "photo") (id "foo")))) ;; type が quote のものを抽出する gosh> (let ((sxml '((post (|@| (type "quote") (id "547214365"))) (post (|@| (type "quote") (id "1234567890"))) (post (|@| (type "photo") (id "foo")))))) (filter-list-by (lambda (x) (get-value-from-sxml 'type x)) "quote" equal? sxml)) ((post (|@| (type "quote") (id "547214365"))) (post (|@| (type "quote") (id "1234567890")))) ;; 当然だけど、 quot (存在しないもの)を指定したら空リストが戻る gosh> (let ((sxml '((post (|@| (type "quote") (id "547214365"))) (post (|@| (type "quote") (id "1234567890"))) (post (|@| (type "photo") (id "foo")))))) (filter-list-by (lambda (x) (get-value-from-sxml 'type x)) "quot" equal? sxml)) ()
こういうフィルタリングする関数は定石としてどのように処理するんだろう? Lisp の定石集みたいなのがあるといいなと、ふと思いました。