トップ «前の日記(2007-08-20) 最新 次の日記(2007-08-22)» 編集

2007-08-21 [長年日記]

_ Hash と map と key の順序

[ruby-list:43857] Hashへの生成順は保障されないのか?

ここから、本人は放っといて Hash が順序を保持してくれると嬉しいときはある、いやいやそれはインタ−フェイスが似ていればいいんであって map 使えばいいじゃん?とか話が膨らむ辺りがステキなわけですが。

以前 PHP の array はマップだってマニュアルにも書いてある で触れたように、PHP 使いが他の環境に移ってまず最初に面食らうのはここじゃないかと思う。(SQL が分かるのならそれはそれでそんなもんだと思うかもしれない。)個人的には PHP の array は遅い遅いとかつて評判だった頃からこの map 方式の array にはいい印象を抱いていない。順序の保持は必ずしも人間の直感に従うわけではなく、例えばすでに生成された array の中身を書き換えた際、その添字が数値でないなら修正した値がいちばん最後になったりするわけです。

BEFORE

$a['foo'] = 'hoge';
$a['bar'] = 'fuga';

処理

$a['foo'] = 'hogege';

AFTER

$a['bar'] = 'fuga';
$a['foo'] = 'hogege';

みたいな*1

これって、どうせ順序を「保持」するなら BEFORE の方を「保持」してほしくないすか?

こういう罠があるので、結局順序が必要な場合は別個に array で*2保持しておいて、そこから key を取り出してそれを利用してアクセスする、という方法を採ってたりします。どうしても順序が大事な場合だけね。

※ ちなみに上の例に関しては、自分の扱ったものの中で実際に順序が思っていたのと違う場合があり、じゃあ別に持てばいいやとさっさと切り替えてしまったもので、その後深く追跡したりはしてないです。

つかむしろ PHP に素の Hash 欲しいです。その方が速いなら、だけど。

……。

なんと! Ruby 1.9 の Hash は順序を保持するパッチが入ってしまった! 当面は仕様として明記しないようです。

Tags: Ruby PHP

*1 未テスト注意。あくまで感覚をつかんでもらうための例ですので。

*2 PHP だと結局全部 array なんだけど