array_splice()関数の動きを整理する

PHParray_splice()関数は、配列操作関数の万能選手。単独で様々な操作が可能です。しかし反面、オプションが多くて挙動が分かりにくい。そこで、基本事項を整理しておきます。


まずは引数と戻り値について。
array array_splice ( array &$input , int $offset [, int $length = 0 [, mixed $replacement ]] )
$inputを参照渡しして、$offsetの位置をスタート地点とし、$lengthぶん進んだ位置までを切り取ります。置換対象の指定があれば、切り取った後で置換対象を挿入します。array_splice()は切り取られた配列を返します。


次に、最もシンプルな使い方。
$data = range(1, 9); // 1から9までを含む配列を生成
array_splice($data, 2);
print_r($data);
// Array ( [0] => 1 [1] => 2 )
$dataの中で、最初(0)から指定オフセット(この場合は2)のぶんだけ進んだ位置(2)までをスタート地点とします。$lengthの指定が無い場合、最後まで切り取ります。

$lengthを指定してみると、
$data = range(1, 9);
print_r(array_splice($data, 2, 3));
// Array ( [0] => 3 [1] => 4 [2] => 5 )
print_r($data);
// Array ( [0] => 1 [1] => 2 [2] => 6 [3] => 7 [4] => 8 [5] => 9 )
インデックス2の地点([2] => 3)から3つ切り取っています。

置換も試してみる。
$data = range(1, 9);
$replacement  = array('a', 'b', 'c');
print_r(array_splice($data, 2, 6, $replacement));
print_r($data);
// Array ( [0] => 1 [1] => 2 [2] => a [3] => b [4] => c [5] => 9 )
今度は$lengthに6を指定しているので、インデックス2の地点からスタートして、6個要素を切り取り、インデックス2の地点から置換対象の配列を挿入しています。


次に、$offsetに負の数(-5)を指定してみます。
$data = range(1, 9);
array_splice($data, -5);
print_r($data);
// Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 )
今度は、配列の最後の地点([8] => 9)から数えて5つ要素を切り取っています。

ここで、$lengthを指定してみると…
$data = range(1, 9);
print_r(array_splice($data, -5, 3));
// Array ( [0] => 5 [1] => 6 [2] => 7 )
print_r($data);
// Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 8 [5] => 9 )
最後の地点から数えて5つ目([4] => 5)からスタートし、後ろに向かって3つぶん要素を切り取っています。では、$lengthに負の数を指定すると…
$data = range(1, 9);
print_r(array_splice($data, -5, -3));
// Array ( [0] => 5 [1] => 6 )
print_r($data);
// Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 7 [5] => 8 [6] => 9 )
$lengthに負の数を指定した場合は、[4] => 5から前に向かって3つぶん… ではなく、配列の後ろから、|$length|(絶対値)ぶんを残して切り取ります。この場合は-3を指定しているので、配列の後ろから数えて、|-3| = 3つぶん残しています。-2なら最後の2つ、-1なら最後の1つだけが残ります。

$offsetに正の数、$lengthに負の数、というパターンも試しておきます。
$data = range(1, 9);
print_r(array_splice($data, 1, -4));
// Array ( [0] => 2 [1] => 3 [2] => 4 [3] => 5 )
print_r($data);
// Array ( [0] => 1 [1] => 6 [2] => 7 [3] => 8 [4] => 9 )
インデックス1の地点(1 => 2)を開始地点として、配列の後ろから|-4| = 4つ要素を残しているのが分かります。


理解に時間がかかったのは、$lengthが負の数であるパターンですね。このように、ちょっと関数の挙動を調べたい、っていう状況では、ローカルでもいいですが、インターネット環境があるならllevalがオススメです。利点は、出力が見やすいことと、テスト用のファイルを作らなくても良いところ。