Hashクラスを利用して入り込んだ配列操作を楽に行う

PHPでは配列でデータを持たせて操作させるということが多々あります。配列は便利なデータ構造ですがデータ量が多くなると入れ子構造になりがちでネストが深いとその要素にアクセスするのに手間がかかります。

CakePHPが提供するHashというユーティリティクラスを利用することでそんな面倒な操作を楽にできるのです。

いくつかメソッドを紹介したいと思います。

extractメソッド

extractを使うことで、配列もしくはArrayAccessインターフェースを実装したオブジェクトから好きなパスに沿ったデータを手早く取り出すことができます。もはやデータ構造をループする必要はありません。その代わりに欲しい要素を絞り込むパス式を使うのです。

だそうです。

// 普通の使い方:
$users = [
    ['id' => 1, 'name' => 'mark'],
    ['id' => 2, 'name' => 'jane'],
    ['id' => 3, 'name' => 'sally'],
    ['id' => 4, 'name' => 'jose'],
];
$results = Hash::extract($users, '{n}.id');
// $results は以下のとおり:
// [1,2,3,4];

insertメソッド

挿入です。引数で指定した配列のパスに値を挿入します。



$a = [ 'pages' => ['name' => 'page'] ]; $result = Hash::insert($a, 'files', ['name' => 'files']); // $result は以下のようになります: [ [pages] => [ [name] => page ] [files] => [ [name] => files ] ]
$data = [
    0 => ['up' => true, 'Item' => ['id' => 1, 'title' => 'first']],
    1 => ['Item' => ['id' => 2, 'title' => 'second']],
    2 => ['Item' => ['id' => 3, 'title' => 'third']],
    3 => ['up' => true, 'Item' => ['id' => 4, 'title' => 'fourth']],
    4 => ['Item' => ['id' => 5, 'title' => 'fifth']],
];
$result = Hash::insert($data, '{n}[up].Item[id=4].new', 9);
/* $result は以下のようになります:
    [
        ['up' => true, 'Item' => ['id' => 1, 'title' => 'first']],
        ['Item' => ['id' => 2, 'title' => 'second']],
        ['Item' => ['id' => 3, 'title' => 'third']],
        ['up' => true, 'Item' => ['id' => 4, 'title' => 'fourth', 'new' => 9]],
        ['Item' => ['id' => 5, 'title' => 'fifth']],
    ]
*/

こんな感じで深いところにも比較的簡単に挿入できます。

removeメソッド

要素の削除です。使い方はinsertと同じなので省略…

containsメソッド

一方のハッシュや配列の中に、もう一方のキーと値が厳密に見てすべて存在しているかを判定します。

第一引数の配列に第二引数の配列の要素が全て存在しているかをチェックします。

$a = [
    0 => ['name' => 'main'],
    1 => ['name' => 'about']
];
$b = [
    0 => ['name' => 'main'],
    1 => ['name' => 'about'],
    2 => ['name' => 'contact'],
    'a' => 'b'
];

$result = Hash::contains($a, $a);
// true
$result = Hash::contains($a, $b);
// false
$result = Hash::contains($b, $a);
// true

flattenメソッド

多次元配列を一次元配列に変換します。

$arr = [
    [
        'Post' => ['id' => '1', 'title' => 'First Post'],
        'Author' => ['id' => '1', 'user' => 'Kyle'],
    ],
    [
        'Post' => ['id' => '2', 'title' => 'Second Post'],
        'Author' => ['id' => '3', 'user' => 'Crystal'],
    ],
];
$res = Hash::flatten($arr);
/* $res は以下のようになります:
    [
        [0.Post.id] => 1
        [0.Post.title] => First Post
        [0.Author.id] => 1
        [0.Author.user] => Kyle
        [1.Post.id] => 2
        [1.Post.title] => Second Post
        [1.Author.id] => 3
        [1.Author.user] => Crystal
    ]
*/

expandメソッド

flattenの逆です。

他にもいくつかのメソッドがあったのですがよく使いそうなものと面白そうなものをピックアップしました。flattenメソッドが面白いなと思ったのですが、 多次元配列を一次元配列にflattenメソッドで変換しておくと見やすくなるときもあるしアクセスしやすい場合もありそうです。