Edited at

PHPで連想配列の任意の位置に要素を挿入・削除する

More than 3 years have passed since last update.

Qiita初投稿です。自分のブログに書いてたのを転載してみた。

PHPの配列関数には、配列の任意の位置に要素を挿入したり、任意の位置から要素を削除したりできるものがない。つとに連想配列に対して、substr的な感覚で要素の挿入・削除が出来たら幸せになれるのになぁ…と、とあるアプリケーションの開発をしていて、痛切にそう思った。

それなら、独自関数として作ってしまうのが手っ取り早い──で、早速作ってみた。

その名もずばり、array_insert()array_delete()だ!

まぁ、思った以上に色んなケースで利用できるんではないかと。


配列の任意の位置に要素を挿入


array_insert()

/**

* 配列(連想配列にも対応)の指定位置に要素(配列にも対応)を挿入して、挿入後の配列を返す
*
* @param array &$base_array 挿入したい配列
* @param mixed $insert_value 挿入する値(文字列、数値、配列のいずれか)
* @param int $position 挿入位置(省略可能。先頭は0、省略時は配列末尾に挿入される)
* @return boolean 挿入成功時にtrue
**/

function array_insert(&$base_array, $insert_value, $position=null) {
if (!is_array($base_array))
return false;
$position = is_null($position) ? count($base_array) : intval($position);
$base_keys = array_keys($base_array);
$base_values = array_values($base_array);
if (is_array($insert_value)) {
$insert_keys = array_keys($insert_value);
$insert_values = array_values($insert_value);
} else {
$insert_keys = array(0);
$insert_values = array($insert_value);
}
$insert_keys_after = array_splice($base_keys, $position);
$insert_values_after = array_splice($base_values, $position);
foreach ($insert_keys as $insert_keys_value) {
array_push($base_keys, $insert_keys_value);
}
foreach ($insert_values as $insert_values_value) {
array_push($base_values, $insert_values_value);
}
$base_keys = array_merge($base_keys, $insert_keys_after);
$is_key_numric = true;
foreach ($base_keys as $key_value) {
if (!is_integer($key_value)) {
$is_key_numric = false;
break;
}
}
$base_values = array_merge($base_values, $insert_values_after);
if ($is_key_numric) {
$base_array = $base_values;
} else {
$base_array = array_combine($base_keys, $base_values);
}
return true;
}


配列の任意の位置から指定数分の要素を削除


array_delete()

/**

* 配列(連想配列にも対応)の任意の位置から指定数分の要素を削除して、削除後の配列を返す
*
* @param array &$base_array 要素を削除したい配列
* @param int $delete_position 削除を開始する要素位置
* @param int $delete_items 削除する要素数(省略可能。省略時は1つだけ削除)
* @param boolean $reroll_index 削除後の配列の添字振り直しフラグ(省略可能。省略時はtrueで添字を振り直す。※数値添字のみの配列でない場合は振り直しは行わない)
* @return boolean 削除成功時にtrue
**/

function array_delete(&$base_array, $delete_position=null, $delete_items=1, $reroll_index=true) {
if (!is_array($base_array))
return false;
if (is_null($delete_position) || !is_integer($delete_position))
return false;
if (!is_integer($delete_items) || intval($delete_items) == 0)
return false;
$index_num = 0;
foreach ($base_array as $key => $value) {
if ($delete_position == $index_num) {
unset($base_array[$key]);
$delete_items--;
$delete_position++;
}
if ($delete_items == 0) {
break;
}
$index_num++;
}
$is_key_numric = true;
foreach (array_keys($base_array) as $key_value) {
if (!is_integer($key_value)) {
$is_key_numric = false;
break;
}
}
if ($is_key_numric && $reroll_index) {
$base_array = array_merge($base_array, array());
}
return true;
}


使用例

$base_array = ['A', 'B', 'C', 'D'];

$insert_data = 'Z';

// 配列(一次元)の指定位置に要素(値)を挿入する
array_insert($base_array, $insert_data, 3);
var_dump($base_array);

----
array(5) {
[0]=> string(1) "A"
[1]=> string(1) "B"
[2]=> string(1) "C"
[3]=> string(1) "Z"
[4]=> string(1) "D"
}

$base_array = ['A'=>'a', 'B'=>'b', 'C'=>'c', 'D'=>'d'];

$insert_data = ['X'=>'x', 'Y'=>'y'];

// 連想配列の指定位置に要素(配列)を挿入する
array_insert($base_array, $insert_data, 3);
var_dump($base_array);

----
array(6) {
["A"]=> string(1) "a"
["B"]=> string(1) "b"
["C"]=> string(1) "c"
["X"]=> string(1) "x"
["Y"]=> string(1) "y"
["D"]=> string(1) "d"
}

$base_array = ['A'=>'a', 'B'=>'b', 'C'=>'c', 'D'=>'d'];

// 連想配列の指定位置から指定数分の要素を削除する
array_delete($base_array, 1, 2);
var_dump($base_array);

----
array(2) {
["A"]=> string(1) "a"
["D"]=> string(1) "d"
}

$base_array = ['A', 'B', 'C', 'D'];

// 配列(一次元)の指定位置から指定数分の要素を削除し、添字は振り直さない
array_delete($base_array, 2, 1, false);
var_dump($base_array);

----
array(3) {
[0]=> string(1) "A"
[1]=> string(1) "B"
[3]=> string(1) "D"
}

個人的に、array_delete()substr() ライクに使えるのが結構お気に入りだったり。