gallu’s blog

エンジニアでゲーマーで講師で占い師なおいちゃんのブログです。

配列と配列と配列

まてこら。
えと…タイトルをちゃんと書き直しませう。


タイトルは「vectorとlistとhash」。
全部「配列」ってニュアンスで捉えられやすいのですが、実際問題大分に声質が違います。性質だってばさ(ATOKが本当に間違えたのでおもしろいからそのまま保存w)。


んと。とりあえず配列ってのは…いいよね説明いらないよね?(手抜き)
で。通常、一番シンプルに
□□□□□□□□□□
ってイメージで考える感じで。
コレを

  array = □□□□□□□□□□

とかしてみませう。
arrayは配列で、大抵の言語において、添え字を使って「何番目の要素よこしぃや」と指定します。

  array = □□□□□□□□□□
  mono = array[3];

こげな感じですな。これを、実際にメモリに格納する場合。おおよそ「□十個分のメモリ領域をがつんとレンタルして格納」って方法を使います。一番シンプル。
これがvectorです。
まぁvectorは「可変長配列」ではあるのですが。実際、vectorの可変ってのは「おけつに要素を足したりおけつの要素を削ったり」です。
つまり

  array = □□□□□□□□□□
  array.add(■■■);

とやってarrayが□□□□□□□□□□■■■になったり、その後末尾を削除したり(通常、iteratorを引数に渡しますな)。
いやまぁ「真ん中の要素を削除」が出来ないわけではないのですが、処理的にあんまり美味しくありません。「真ん中にデータを追加」は、削除以上にしんどいです。っつかやるな。


ちゅぎ。
list構造ってのがあります。えと…わからなければググれw*1
とりあえず「双方向list」を前提に。
list構造は「自分のデータの前後のデータ」についてそれぞれポインタを持っています。
なので、先ほどvectorに出てきた「真ん中の要素の削除」が非常に簡単にできます。で、list構造なら「真ん中にデータを追加」もおちゃづけさらさら。
ただ「真ん中の要素とかへのランダムアクセス」にはちょいと性能的に不利だったりします(その辺はvectorのほうが有利)。


ラスト。
hashってのは…うん上述とは根本的におもむきが違うです。
んと…ハッシュテーブルってキーワードでググるとよろしいかなぁとか思うですが。
vectorとlistはいずれも添え字には「数字」しか使えない訳なのですが。だって「先頭からの順番」だし。
hashは、添え字に「任意の文字」を使えるのが最大の特徴。
ちなみにhashはその性質上「順番」って概念がないです。だって添え字は「ハッシュ値」になって、その辺に格納されているんですもの。


ここまでがどこの言語でも言える話。
で、以下、PHPに固有の話。


「え〜ハッシュに順番ないとかいうけどforeachで回せるぢゃんちゃんと順番おぼえてるぢゃん」という反論が出る事は百万も承知の助。
答えは、ここ。
http://www.php.net/manual/ja/language.types.array.php

PHP の配列は、実際には順番付けられたマップです。マップは型の一種で、 値をキーに関連付けます。

とりあえず「mapとhashは同じものだ」と思ってくださいいやまぁ大体間違ってないので。
つまりPHPの配列は「listでhashである」わけです。怖いですねぇ。


んと。何が怖いかっていうと。
配列をプログラムで、設計で、実際に使う時使いたいとき。
その配列をvectorのイメージで持っているのか、listで持っているのか、hashでもっているのか、で、大分設計のニュアンスが変わったりするです。
で、そこでその辺を意識しないと、意外なところで足下をすくわれたりするです。だれも救っちゃくれませんが。


なので。
引数にする時returnで返すとき。
その配列は、vectorなのかlistなのか(この二つはまぁまだ混ぜても平気)hashなのか、きちんと意識しておくとちょっといいことがある…かも、しれません。

*1:まぁ偉そう