blog/content/post/2010-05-15-00001361.md

107 lines
9.5 KiB
Markdown

---
title: リストをフィルターする関数
author: kazu634
date: 2010-05-15
url: /2010/05/15/_1525/
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
---
<div class="section">
<p>
<a href="http://d.hatena.ne.jp/sirocco634/20100511#1273586076" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/sirocco634/20100511#1273586076', '2010-05-11 &#8211; 武蔵の日記');" target="_blank">2010-05-11 &#8211; 武蔵の日記</a>で予告していたリストをフィルタリングする関数を作成してみました:
</p>
<h4>
作成してみた関数
</h4>
<pre class="syntax-highlight">
<span class="synSpecial">(</span>define <span class="synSpecial">(</span>filter-list-by key-fn value cmp xs<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">map</span> <span class="synStatement">cdr</span>
<span class="synSpecial">(</span>filter <span class="synSpecial">(</span><span class="synStatement">lambda</span> <span class="synSpecial">(</span>x<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">if</span> <span class="synSpecial">(</span>cmp <span class="synSpecial">(</span><span class="synStatement">car</span> x<span class="synSpecial">)</span> value<span class="synSpecial">)</span>
#t
#f<span class="synSpecial">))</span>
<span class="synSpecial">(</span><span class="synStatement">map</span>
<span class="synSpecial">(</span><span class="synStatement">lambda</span> <span class="synSpecial">(</span>x<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">cons</span> <span class="synSpecial">(</span>key-fn x<span class="synSpecial">)</span> x<span class="synSpecial">))</span>
xs<span class="synSpecial">))))</span>
</pre>
<h4>
実行例
</h4>
<pre class="syntax-highlight">
<span class="synComment">;; 前提になるライブラリを読み込む</span>
gosh&#62; <span class="synSpecial">(</span>use srfi-1<span class="synSpecial">)</span>
#&#60;undef&#62;
gosh&#62; <span class="synSpecial">(</span>use sxml.ssax<span class="synSpecial">)</span>
#&#60;undef&#62;
gosh&#62; <span class="synSpecial">(</span>use sxml.sxpath<span class="synSpecial">)</span>
#&#60;undef&#62;
<span class="synComment">;; 前提になる get-value-from-sxml を定義</span>
gosh&#62; <span class="synSpecial">(</span>define <span class="synSpecial">(</span>get-value-from-sxml sxpath sxml<span class="synSpecial">)</span>
<span class="synSpecial">((</span>if-car-sxpath <span class="synPreProc">`(</span><span class="synStatement">//</span> ,sxpath <span class="synType">*text*</span><span class="synPreProc">)</span><span class="synSpecial">)</span> sxml<span class="synSpecial">))</span>
get-value-from-sxml
<span class="synComment">;; type が photo のものを抽出する</span>
gosh&#62; <span class="synSpecial">(</span><span class="synStatement">let</span> <span class="synSpecial">((</span>sxml
<span class="synSpecial">'((</span>post <span class="synSpecial">(</span>|@|
<span class="synSpecial">(</span><span class="synStatement">type</span> <span class="synConstant">&#34;quote&#34;</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span>id <span class="synConstant">&#34;547214365&#34;</span><span class="synSpecial">)))</span>
<span class="synSpecial">(</span>post <span class="synSpecial">(</span>|@|
<span class="synSpecial">(</span><span class="synStatement">type</span> <span class="synConstant">&#34;quote&#34;</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span>id <span class="synConstant">&#34;1234567890&#34;</span><span class="synSpecial">)))</span>
<span class="synSpecial">(</span>post <span class="synSpecial">(</span>|@|
<span class="synSpecial">(</span><span class="synStatement">type</span> <span class="synConstant">&#34;photo&#34;</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span>id <span class="synConstant">&#34;foo&#34;</span><span class="synSpecial">))))))</span>
<span class="synSpecial">(</span>filter-list-by <span class="synSpecial">(</span><span class="synStatement">lambda</span> <span class="synSpecial">(</span>x<span class="synSpecial">)</span>
<span class="synSpecial">(</span>get-value-from-sxml <span class="synSpecial">'</span><span class="synIdentifier">type</span> x<span class="synSpecial">))</span>
<span class="synConstant">&#34;photo&#34;</span>
<span class="synStatement">equal</span>?
sxml<span class="synSpecial">))</span>
<span class="synSpecial">((</span>post <span class="synSpecial">(|@|</span> <span class="synSpecial">(</span><span class="synStatement">type</span> <span class="synConstant">&#34;photo&#34;</span><span class="synSpecial">)</span> <span class="synSpecial">(</span>id <span class="synConstant">&#34;foo&#34;</span><span class="synSpecial">))))</span>
<span class="synComment">;; type が quote のものを抽出する</span>
gosh&#62; <span class="synSpecial">(</span><span class="synStatement">let</span> <span class="synSpecial">((</span>sxml
<span class="synSpecial">'((</span>post <span class="synSpecial">(</span>|@|
<span class="synSpecial">(</span><span class="synStatement">type</span> <span class="synConstant">&#34;quote&#34;</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span>id <span class="synConstant">&#34;547214365&#34;</span><span class="synSpecial">)))</span>
<span class="synSpecial">(</span>post <span class="synSpecial">(</span>|@|
<span class="synSpecial">(</span><span class="synStatement">type</span> <span class="synConstant">&#34;quote&#34;</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span>id <span class="synConstant">&#34;1234567890&#34;</span><span class="synSpecial">)))</span>
<span class="synSpecial">(</span>post <span class="synSpecial">(</span>|@|
<span class="synSpecial">(</span><span class="synStatement">type</span> <span class="synConstant">&#34;photo&#34;</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span>id <span class="synConstant">&#34;foo&#34;</span><span class="synSpecial">))))))</span>
<span class="synSpecial">(</span>filter-list-by <span class="synSpecial">(</span><span class="synStatement">lambda</span> <span class="synSpecial">(</span>x<span class="synSpecial">)</span>
<span class="synSpecial">(</span>get-value-from-sxml <span class="synSpecial">'</span><span class="synIdentifier">type</span> x<span class="synSpecial">))</span>
<span class="synConstant">&#34;quote&#34;</span>
<span class="synStatement">equal</span>?
sxml<span class="synSpecial">))</span>
<span class="synSpecial">((</span>post <span class="synSpecial">(|@|</span> <span class="synSpecial">(</span><span class="synStatement">type</span> <span class="synConstant">&#34;quote&#34;</span><span class="synSpecial">)</span> <span class="synSpecial">(</span>id <span class="synConstant">&#34;547214365&#34;</span><span class="synSpecial">)))</span> <span class="synSpecial">(</span>post <span class="synSpecial">(|@|</span> <span class="synSpecial">(</span><span class="synStatement">type</span> <span class="synConstant">&#34;quote&#34;</span><span class="synSpecial">)</span> <span class="synSpecial">(</span>id <span class="synConstant">&#34;1234567890&#34;</span><span class="synSpecial">))))</span>
<span class="synComment">;; 当然だけど、 quot (存在しないもの)を指定したら空リストが戻る</span>
gosh&#62; <span class="synSpecial">(</span><span class="synStatement">let</span> <span class="synSpecial">((</span>sxml
<span class="synSpecial">'((</span>post <span class="synSpecial">(</span>|@|
<span class="synSpecial">(</span><span class="synStatement">type</span> <span class="synConstant">&#34;quote&#34;</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span>id <span class="synConstant">&#34;547214365&#34;</span><span class="synSpecial">)))</span>
<span class="synSpecial">(</span>post <span class="synSpecial">(</span>|@|
<span class="synSpecial">(</span><span class="synStatement">type</span> <span class="synConstant">&#34;quote&#34;</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span>id <span class="synConstant">&#34;1234567890&#34;</span><span class="synSpecial">)))</span>
<span class="synSpecial">(</span>post <span class="synSpecial">(</span>|@|
<span class="synSpecial">(</span><span class="synStatement">type</span> <span class="synConstant">&#34;photo&#34;</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span>id <span class="synConstant">&#34;foo&#34;</span><span class="synSpecial">))))))</span>
<span class="synSpecial">(</span>filter-list-by <span class="synSpecial">(</span><span class="synStatement">lambda</span> <span class="synSpecial">(</span>x<span class="synSpecial">)</span>
<span class="synSpecial">(</span>get-value-from-sxml <span class="synSpecial">'</span><span class="synIdentifier">type</span> x<span class="synSpecial">))</span>
<span class="synConstant">&#34;quot&#34;</span>
<span class="synStatement">equal</span>?
sxml<span class="synSpecial">))</span>
<span class="synSpecial">()</span>
</pre>
<p>
こういうフィルタリングする関数は定石としてどのように処理するんだろう? Lisp の定石集みたいなのがあるといいなと、ふと思いました。
</p>
</div>