IT戦記さんで、「Javascriptの配列と連想配列の違い」が解説されてました。
で、おなじみの Javascript用フレームワークの prototype.js(いつのまにか公式サイトがリニューアルされて、ドキュメント等がかなり充実してます)を使ってて はまったポイントが以前あったのを思い出したので、ちょっと書いてみようと思います。というか、なんか prototype.jsの初歩的な解説になってるかもしれない・・・
というわけで、かなり久々の技術エントリ。プログラミングしない方にはごめんなさひ。
prototype.jsにおける配列
prototype.jsでは、配列 (Arrayクラス)は prototypeが拡張されていて、Enumerableクラスを継承(Object.extend)しています。 なので、for in 構文を使うとEnumerableのメンバ関数まで列挙してしまいます。
var array = new Array( 'hoge', 'fuga', 'piyo' ); for( var i in array ) { document.write( array[i] + "<br />\n" ); }
結果
hoge
fuga
piyo
function (iterator) { ... // Enumerableの関数の中身
function (number, iterator) { ...
:
というわけで、prototype.js では通常のfor文を使う、 ・・・事もできますが、前述の通り Arrayクラスは Enumerableクラスを継承しているので、Enumerableクラスで定義されている イテレータ風のメソッドを使う事ができます。せっかくなので、こっちを使ってみましょう。
例えば、each関数を使うとこんな感じ。
var array = new Array( 'hoge', 'fuga', 'piyo' ); array.each( function( value, index ){ document.write( index + ':' + value + '<br />\n' ); } );
結果
0:hoge 1:fuga 2:piyo
さらに、Javascriptは関数もオブジェクトなのでこんな書き方も出来ます。
var array = new Array( 'hoge', 'fuga', 'piyo' ); var func = function( value, index ){ document.write( index + ':' + value + '<br />\n' ); }; array.each( func );
結果
(1個前のと同じ。)
関数の中に関数が入っててわかりにくいのですが、配列の要素ごとに内側の(eachの引数に当たる)関数が呼び出される格好になります。 わかりやすく書くと、array.each()のところでこんな感じで置き換わっているイメージです。
func( 'hoge', 0 ); func( 'fuga', 1 ); // それぞれ、func関数(document.writeしてるやつ)が実行される。 func( 'piyo', 2 );
他にも、any や allなどといった関数が追加されているので、マニュアル(や日本語解説)を覗いてみてください。
で、前にはまった点が これらの Enumerableクラスの関数はあくまで配列が対象なので、連想配列の要素は鮮やかに無視します。 なので、
var array = new Array(); array[ 'hoge' ] = 'hoge hoge'; array[ 'fuga' ] = 'fuga fuga'; array[ 'piyo' ] = 'piyo piyo';
という連想配列を、以下のように each()関数で回しても何も起こりません。
array.each( function( value, index ) { document.write( value + "<br />\n" ); } );
結果
(何も表示されず。)
というわけで、無理やり配列を使うのであれば、例えば配列の要素にオブジェクトとして追加して
var array = new Array(); array.push( { id: 'hoge', value: 'hoge hoge' } ); // pushは配列の末尾に要素を追加するメソッド array.push( { id: 'fuga', value: 'fuga fuga' } ); // 組み込みなので prototype.jsが無くても使えます。 array.push( { id: 'piyo', value: 'piyo piyo' } ); // {}の間は JSON形式で記述したオブジェクト。
以下のように回してやればOKです。
array.each( function( obj, index ) { document.write( obj.value + "<br />\n" ); } );
特定の要素を見つける場合は、find関数を使って、
function get( id ) { return array.find( function( obj, index ) { return obj.id == id; } ); } var fuga = get( 'fuga' ); document.write( fuga.value );
結果
fuga fuga
とか書く事ができます。
とはいえ、いちいちこんな回りくどい書き方するのもメンドウですし非効率的なので、それなら最初から連想配列を使いましょう。 というわけで次回は連想配列編。Hashクラスにもちょこっと触れます。
前後編にするとブログのネタが稼げますね。
であ、また。