セレクターその19(jQueryの独自フィルター firstフィルター / lastフィルター)

う〜ん、わかんねぇ。。


first-child/last-childセレクターが共通の親要素を持つ要素から最初(または最後)の要素を選択するのに対して、
last/firstフィルターは指定したセレクターで最初(最後)に登場する要素を指定できます。
first-child、last-childとの違いが分からん。
例によって自前タグを追加して実験。

<html>
  <head>
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">google.load("jquery", "1.3.2");</script>
    <script type="text/javascript">
      $(function() {
        $("li:first").css("color","red");
        $("li:last").css("color","red");
        $("div:first").css("color","blue");
        $("div:last").css("color","green");
        $("div div div:first").css("color","blue");
        $("div div div:last").css("color","green");
      })
    </script>
  </head>
  <body>
    <div>さいしょ</div>
    <ul>
      <li>テキストテキストテキストテキストテキスト</li>
      <li>テキストテキストテキストテキストテキスト</li>
      <li>テキストテキストテキストテキストテキスト</li>
      <li>テキストテキストテキストテキストテキスト</li>
    </ul>
    <div>
      ほげほげ
      <div>ブロックのなかのさいしょ</div>
      <div>ブロックのなかのまんなか</div>
      <div>ブロックのなかのさいご</div>
      <div>
	<div>hogehoge</div>
	<div>fugafuga</div>
	<div>mogamoga</div>
      </div>
      ふがふが
    </div>
    <div>さいご</div>
  </body>
</html>

どうやら子孫セレクターとかと併用しない場合はドキュメント中で最初/最後に出てきたものがfirst/lastで指定される模様。
子孫セレクターを使用すれば指定したタグツリーに対しても適用できるのかな?

セレクターその20(jQueryの独自フィルター evenフィルター / oddフィルター)

このセレクターは前にnth-child擬似クラスでちょっと出てきたからまぁ迷わんだろう。

<html>
  <head>
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">google.load("jquery", "1.3.2");</script>
    <script type="text/javascript">
      $(function() {
        $("li:odd").css("color","red");
        $("li:even").css("color","blue");
      })
    </script>
  </head>
  <body>
    <ul>
      <li>ぱんぱかぱんつ</li>
      <li>ぱんぱかぱんつ</li>
      <li>ぱんぱかぱんつ</li>
      <li>ぱんぱかぱんつ</li>
    </ul>
  </body>
</html>

偶数行は青文字で、奇数行は赤文字で表示されると。

セレクターその21(jQueryの独自フィルター eqフィルター / gtフィルター / ltフィルター)

これは今までのセレクターでは代用できないかなぁ。覚えてた方が便利だろ。

<html>
  <head>
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">google.load("jquery", "1.3.2");</script>
    <script type="text/javascript">
      $(function() {
        $("li:lt(2)").css("color","red");
        $("li:eq(2)").css("color","blue");
        $("li:gt(2)").css("color","green");
      })
    </script>
  </head>
  <body>
    <ul>
      <li>ぱんぱかぱんつ</li>
      <li>ぱんぱかぱんつ</li>
      <li>ぱんぱかぱんつ</li>
      <li>ぱんぱかぱんつ</li>
    </ul>
  </body>
</html>

1、2行目が赤文字、3行目が青文字、4行目が緑文字になる。

セレクターその22(jQueryの独自フィルター headerフィルター/containsフィルター/hasフィルター/parentフィルター)


header :h1〜h6要素のこと。独自フィルターにするほど使うのか?
contains:特定の文字列が含まれている要素。
has   :特定の「要素」が含まれている要素。
parent :子要素やテキストを含む要素を指定可能。IsParent?みたいなニュアンスかな。
とりあえず競合が発生しないように全部いれたぜ。

<html>
  <head>
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">google.load("jquery", "1.3.2");</script>
    <script type="text/javascript">
      $(function() {
        $(":header").css("color","red");
        $("li:contains('つでぱ')").css("color","blue");
        $("li:has(strong)").css("color","green");
        $("div ul li:parent").css("color","yellow");
      })
    </script>
  </head>
  <body>
    <h1>h1タグですよ</h1>
    <p>テキストテキストテキストテキストテキスト</p>
    <h6>h6タグですよ</h6>
    <ul>
      <li><strong>ぱんぱか</strong>ぱんつ</li>
      <li>ぱんぱかぱんつ</li>
      <li>ぱんぱかぱんつ</li>
      <li>ぱんぱかぱんつでぱんぱかぱん</li>
    </ul>
    <div>
      <ul>
	<li>ぱんぱかぱんつ</li>
	<li></li>
	<li>ぱんぱかぱんつ</li>
      </ul>
    </div>
  </body>
</html>

よ〜し、これでセレクター終わり!

SICP 問題 1.29 (Simpsonの公式を使った積分計算)

【問題】

Simpsonの公式は上に示したのより更に正確な数値積分法である。
Simpsonの公式を使えば、a から b までの関数 f の積分は、


偶整数 n に対し、

h = (b-a)/n

また、

y_k = f(a+kh) として、

(h/3)[y_0 + 4・y_1 + 2・y_2 + 4・y_3 + 2・y_4 + ... + 2・y_(n-2) + 4・y_(n-1) + y_n]

で近似できる。(n の増加は近似の精度を増加する。)
引数として f, a, b, と n をとり、Simpson公式を使って計算した積分値を返す手続きを定義せよ。
その手続きを使って(n=100 と n=1000で)0 から 1 までcubeを積分し、またその結果を上のintegral手続きの結果と比較せよ。

【解答】

う〜ん、思考プロセスをログに取っていかなくても、すんなりできちゃったなぁ。。
とりあえずコード中にその時考えたことを記録しておこうか。

(define (simpson f a b n)
  ;yの関係式だけでも式にすると結構面倒なので内部手続き化してしまう。
  ;この時注意したのは、
  ; 「hの中で使用されているn」と「yの添字として渡されるk」は別物
  ;だということ。
  (define (y k)
    (f (+ a (* k (/ (- b a) n)))))

  ;名前付き再帰処理を定義。別に内部手続き化しても同じだからお好きな方で。
  (let loop ((k 0)       ;現在処理中の項のインデックスを表現。
	     (answer 0)) ;現在の加算結果(初期値は0とする)
    (cond ((= k 0)
	   ;初期値の場合は係数なしでyを呼ぶ。
	   (loop (+ k 1) (+ answer (y k)))) 
	  ((= k n)
	   ;最終値の計算の場合は係数なしでyを呼び、加算後にh/3を乗算する。
	   (* (/ (/ (- b a) n) 3) (+ answer (y k))))
	  ((odd? k)
	   ;奇数の場合は係数を4にしてyを呼んで加算。
	   (loop (+ k 1) (+ answer (* 4 (y k)))))
	  (else
	   ;偶数の場合は係数を2にしてyを呼んで加算。
	   (loop (+ k 1) (+ answer (* 2 (y k))))))))

定義はこんな感じ。んで、cubeをfとして使いたいのでこれも定義してしまおう。

(define (cube x)
  (* x x x))

さて、この2つの手続きを読み込ませて実行してみる!


gosh> (simpson cube 0 1 100)
1/4
gosh> (simpson cube 0 1 1000)
1/4
gosh>
お〜、ドンピシャ。Gaucheの正確数だっけ?有理数で結果が取得できるぞ。

問題文中には


integral手続きの結果と比較せよ。
とあるので、この問題の前に定義されていたintegral手続きとそれから呼び出されるされるsum手続きもここに記載する。

(define (integral f a b dx)
  (define (add-dx x)
    (+ x dx))
  (* (sum f (+ a (/ dx 2.0)) add-dx b)
     dx))

(define (sum term a next b)
  (if (> a b)
      0
      (+ (term a)
	 (sum term (next a) next b))))

こいつらを読み込ませて、実行してみる。
ちなみにこいつらは小さい値(0.01とか0.001とか)を計算の元ネタとして積分していく。


gosh> (integral cube 0 1 0.01)
0.24998750000000042
gosh> (integral cube 0 1 0.001)
0.249999875000001
gosh> (integral cube 0 1 (/ 1 1000))
0.249999875000001
gosh>
というわけで、その小さい値を有理数にしても、得られる結果は非正確数(だっけ?)になる。
なので、Simpsonの公式を使った結果の方が正確な値を取得できる。