PHP配列トリビア 配列の正体は辞書

忘れそうなのでメモ。

格納順序が不自然で、インデックスは連続している配列があるとする。

<?php
$a = array(0,1,2);
$a[5] = 5;
$a[4] = 4;
$a[3] = 3;
print_r($a);
?>
Array
(
    [0] => 0
    [1] => 1
    [2] => 2
    [5] => 5
    [4] => 4
    [3] => 3
)

foreachでは格納順に処理される。

<?php
foreach($a as $i=>$e){
    echo "[" . $i . "]=". $e . " ";
}
echo "\n";
?>
[0]=0 [1]=1 [2]=2 [5]=5 [4]=4 [3]=3 

正しいインデックス順処理?

<?php
$ak = array_keys($a);
natsort($ak);
foreach($ak as $i){
    echo "[" . $i . "]=". $a[$i] . " ";
}
echo "\n";
?>
[0]=0 [1]=1 [2]=2 [3]=3 [4]=4 [5]=5 

歯抜けキーなしの場合はこれでもいい

<?php
for($i = 0; $i < count($a); $i++){
    echo "[" . $i . "]=". $a[$i] . " ";
}
echo "\n";
?>
[0]=0 [1]=1 [2]=2 [3]=3 [4]=4 [5]=5 

array_pushの実装
0と自然数キーのみの集合のうちで最大の値に1加算したキーと値を末尾に格納

<?php
$b = $a;
array_push($b, 99);
print_r($b);
?>
Array
(
    [0] => 0
    [1] => 1
    [2] => 2
    [5] => 5
    [4] => 4
    [3] => 3
    [6] => 99
)

array_popの実装
格納順で最後の要素を取り出す

<?php
$b = $a;
echo array_pop($b) . "\n";
print_r($b);
?>
3
Array
(
    [0] => 0
    [1] => 1
    [2] => 2
    [5] => 5
    [4] => 4
)

array_unshiftの実装
まずキー0に値を格納し、既存要素を格納順に連続値で再インデックスする

<?php
$b = $a;
array_unshift($b, 99);
print_r($b);
?>
Array
(
    [0] => 99
    [1] => 0
    [2] => 1
    [3] => 2
    [4] => 5
    [5] => 4
    [6] => 3
)

array_shiftの実装
格納順で最初の要素を取り出し、他を格納順に連続値で再インデックスする

<?php
$b = $a;
echo array_shift($b) . "\n";
print_r($b);
?>
0
Array
(
    [0] => 1
    [1] => 2
    [2] => 5
    [3] => 4
    [4] => 3
)

というわけで、使う前にksortをかけて、順不同で格納された歯抜けなし配列を、foreachやarray_シリーズが期待する正常な形式の配列に変換する。

<?php
$b = $a;
ksort($b);
print_r($b);
?>
Array
(
    [0] => 0
    [1] => 1
    [2] => 2
    [3] => 3
    [4] => 4
    [5] => 5
)