Help us understand the problem. What is going on with this article?

文字列キーだけでなく数値キーもきっちりマージさせる(CakePHP編)

More than 5 years have passed since last update.

背景

GET/POST リクエストのパラメータやセッション、データベースのデータ等との同期をとるためによく配列のマージを使うが、Hash::merge() で全部いけるかと思ってたら数値キーはマージされずにどちらも残ってしまい、マージを繰り返すうちに配列の要素がどんどん増えてしまうといった現象が発生してしまっていた。

(参考)
PHP の array_merge() や array_recursive() 等の違いをまとめました | Tips Note

キーが数値型であっても、同じ値のキーについてはマージする配列の値で上書きするようにしたい。

実装

Hash::flatten() でマージする/される配列を一度1次元配列へと平坦化し、マージして Hash::extend() で元に戻す。こうすることで、平坦化された配列のキーは(多次元配列であれば)全て文字列キーになるので、上書きマージが可能となる。

コード

public function arr_merge_overwrite( $array1, $array2 ) {
    // マージする/される配列を平坦化する
    $array1 = Hash::flatten( $array1 );
    $array2 = Hash::flatten( $array2 );

    // マージ
    $return = Hash::merge( $array1, $array2 );

    // マージした配列を通常の配列に戻す
    return Hash::expand( $return );
}

動作例

// 対象データ
$a = array(
    0 => 'blue',
    1 => 'red',
    'a' => 'cyan',
    3 => 'yellow',
);

$b = array(
    1 => 'orange',
    2 => 'green',
    3 => 'purple',
    'a' => 'white',
    'b' => 'black',
);

// 出力
var_dump( arr_merge_overwrite( $a, $b ) );

// array(
//     0 => 'blue',  // $a の値
//     1 => 'orange',  // $b の値($a の値をマージ)
//     'a' => 'white',  // $b の値($a の値をマージ)
//     3 => 'purple',  // $b の値($a の値をマージ)
//     2 => 'green',  // $b の値
//     'b' => 'black',  // $b の値
// );

余談

CakePHP 以外でも使いたいので、標準の関数のみでうまくやる方法があったら知りたいです。
(愚直なやり方としては flatten(), expand() を移植すればどの環境でもできるが、、、)

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away