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

  • 21
    いいね
  • 2
    コメント
この記事は最終更新日から1年以上が経過しています。

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() ライクに使えるのが結構お気に入りだったり。