Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2009-12-09

KMRCLを眺める (34) MAP-AND-REMOVE-NILS

| 23:31 | KMRCLを眺める (34) MAP-AND-REMOVE-NILS - わだばLisperになる を含むブックマーク はてなブックマーク - KMRCLを眺める (34) MAP-AND-REMOVE-NILS - わだばLisperになる

今回は、KMRCLのlisps.lisp中からMAP-AND-REMOVE-NILSです。

名前からしてMAP系の関数を使っていてよくありがちな状況を解決してくれそうです。

定義は

(defun map-and-remove-nils (fn lst)
  "mao a list by function, eliminate elements where fn returns nil"
  (let ((acc nil))
    (dolist (x lst (nreverse acc))
      (let ((val (funcall fn x)))
        (when val (push val acc))))))

こんな感じですが、複数のリストには対応してないんですね。

使われ方としては、

(DEFVAR *L* (ALEXANDRIA:IOTA 25))

(MAP-AND-REMOVE-NILS (LAMBDA (X) (AND (EVENP X) X))
                     *L*)
;⇒ (0 2 4 6 8 10 12 14 16 18 20 22 24)

;; MAP-AND-REMOVE-NILSを使いたくなりそうな場面
(REMOVE NIL
        (MAPCAR (LAMBDA (X) (AND (EVENP X) X))
                *L*))
;⇒ (0 2 4 6 8 10 12 14 16 18 20 22 24)

;; しかし、大抵の場合REMOVE-IF等で済みそう…
(REMOVE-IF-NOT #'EVENP
               *L*)
;⇒ (0 2 4 6 8 10 12 14 16 18 20 22 24)

という感じでしょうか。

ゲスト



トラックバック - http://cadr.g.hatena.ne.jp/g000001/20091209