system
マリンロード

2017.9.19システム開発 

マリンロード

[CakePHP] CakePHPのHashクラスが配列をあれこれするのに便利すぎた

こんにちは。エンジニアの高田です。
きっと知っている方からすれば今さら感満載なんでしょうけど、私最近知りました。
CakePHPの「Hashクラス」。
CakePHPといえば、配列祭りワッショイです。
その配列を便利な形に組み替えたり、抽出したりできるのがCakePHPの「Hashクラス」です。

Hashクラス

まずは、Hashクラスとは。。。
CakePHPに用意されている配列を扱うための便利なツールです。

▽CakePHP Cookbookより
https://book.cakephp.org/2.0/ja/core-utility-libraries/hash.html

Hashクラスにはいくつかのstaticで呼び出せるメソッドが準備されています。

配列から特定の値を取り出せる「Hash::get()」。
配列から特定の配列を取り出せる「Hash::extract()」。
配列から特定の値で配列を組み替えることができる「Hash::combine()」。
配列の中に挿入することができる「Hash::insert()」。
配列からある要素を削除できる「Hash::remove()」。
配列を並び替えることができる「Hash::sort()」。
配列の・・・。

・・・。

このように色々便利なものが準備されています。
詳しくはCakePHP CookBook Hash – 2.xを参照ください。
それではいくつか紹介します。

サンプルデータ

以下の配列をあれこれ操作します。

$data = array(
    0 => array('User' => array('id' => 101, 'name' => '佐藤', 'kana' => 'サトウ', 'group' => 'ホームページG')),
    1 => array('User' => array('id' => 102, 'name' => '田中', 'kana' => 'タナカ', 'group' => 'ホームページG')),
    2 => array('User' => array('id' => 103, 'name' => '鈴木', 'kana' => 'スズキ', 'group' => 'システムG')),
);

print_r($data);

 

Array
(
    [0] => Array
        (
            [User] => Array
                (
                    [id] => 101
                    [name] => 佐藤
                    [kana] => サトウ
                    [group] => ホームページG
                )

        )

    [1] => Array
        (
            [User] => Array
                (
                    [id] => 102
                    [name] => 田中
                    [kana] => タナカ
                    [group] => ホームページG
                )

        )

    [2] => Array
        (
            [User] => Array
                (
                    [id] => 103
                    [name] => 鈴木
                    [kana] => スズキ
                    [group] => システムG
                )

        )

)

Hash::extract(array $data, $path)

「Hash::extract()」は欲しい要素の配列を取り出せるメソッドです。

Userのname要素だけの配列を作りたい

$result = Hash::extract($data, '{n}.User.name');
print_r($result);

 

Array
(
    [0] => 佐藤
    [1] => 田中
    [2] => 鈴木
)

 

UserのgroupがホームページGの人だけ取り出したい

$result = Hash::extract($data, '{n}.User[group=ホームページG]');
print_r($result);

 

Array
(
    [0] => Array
        (
            [id] => 101
            [name] => 佐藤
            [kana] => サトウ
            [group] => ホームページG
        )

    [1] => Array
        (
            [id] => 102
            [name] => 田中
            [kana] => タナカ
            [group] => ホームページG
        )

)

 

Userのidが103のnameを取り出したい

$result = Hash::extract($data, '{n}.User[id=103].name');
print_r($result);

 

Array
(
    [0] => 鈴木
)

 

便利~。では次。

Hash::combine(array $data, $keyPath, $valuePath = null, $groupPath = null)

「Hash::combine()」はキーと値を自由に指定して配列を組み替えることができるメソッドです。第二引数でキーを、第三引数で値を指定します。

Userのidをキーとした配列にしたい

$result = Hash::combine($data, '{n}.User.id', '{n}.User');
print_r($result);

 

Array
(
    [101] => Array
        (
            [id] => 101
            [name] => 佐藤
            [kana] => サトウ
            [group] => ホームページG
        )

    [102] => Array
        (
            [id] => 102
            [name] => 田中
            [kana] => タナカ
            [group] => ホームページG
        )

    [103] => Array
        (
            [id] => 103
            [name] => 鈴木
            [kana] => スズキ
            [group] => システムG
        )

)

 

Userのidをキーとしてgroupでグループ化した配列にしたい

$result = Hash::combine($data, '{n}.User.id', '{n}.User', '{n}.User.group');
print_r($result);

 

Array
(
    [ホームページG] => Array
        (
            [101] => Array
                (
                    [id] => 101
                    [name] => 佐藤
                    [kana] => サトウ
                    [group] => ホームページG
                )

            [102] => Array
                (
                    [id] => 102
                    [name] => 田中
                    [kana] => タナカ
                    [group] => ホームページG
                )

        )

    [システムG] => Array
        (
            [103] => Array
                (
                    [id] => 103
                    [name] => 鈴木
                    [kana] => スズキ
                    [group] => システムG
                )

        )

)

Hash::sort(array $data, $path, $dir, $type = ‘regular’)

「Hash::sort()」はどの次元のどの値によってでもソートすることができます。
第二引数の $dir には asc(昇順) もしくは desc(降順) が指定可能です。
第三引数の $type には次のいずれかを指定することができます。

・regular : 通常のソート。
・numeric : 数値とみなしてソート。
・string : 文字列としてソート。
・natural : ヒューマン・フレンドリー・ソート。例えば、 foo10 が foo2 の下に配置される。このソートには PHP 5.4 以上が必要。

Userのkanaでソートしたい

$result = Hash::sort($data, '{n}.User.kana', 'asc');
print_r($result);

 

Array
(
    [0] => Array
        (
            [User] => Array
                (
                    [id] => 101
                    [name] => 佐藤
                    [kana] => サトウ
                    [group] => ホームページG
                )

        )

    [1] => Array
        (
            [User] => Array
                (
                    [id] => 103
                    [name] => 鈴木
                    [kana] => スズキ
                    [group] => システムG
                )

        )

    [2] => Array
        (
            [User] => Array
                (
                    [id] => 102
                    [name] => 田中
                    [kana] => タナカ
                    [group] => ホームページG
                )

        )

)

 
すごい。
色々できますね。
その他にもformatとかfilterとかdiffとか気になるものがいくつもあります。
CakePHPのCakePHP CookBook Hash – 2.xをご確認ください。

Hash パス構文

ところで各メソッドの引数 $path に「{n}」とか見慣れないものがありますよね。
これはHashクラスのパス構文で以下のような種類があります。

式の種類

式   説明
{n} : 数値キーを意味する。どんな文字列キーでも 数値型のキーでも一致する。
{s} : 文字列キーを意味する。数値文字列を含め、 どんな文字列でも一致する。
{*} : 型に関係なく任意の値を表す。
Foo : 完全に同じ値だった場合のみ一致する。
 
 

属性の絞り込み種別

マッチャー   説明
[id]     記述されたキーと一致する要素に絞り込む。
[id=2]    id が 2 となっている要素に絞り込む。
[id!=2]    id が 2 ではない要素に絞り込む。
[id>2]    id が 2 より大きい要素に絞り込む。
[id>=2]    id が 2 以上の要素に絞り込む。
[id<2]    id が 2 より小さい要素に絞り込む。
[id<=2]    id が 2 以下の要素に絞り込む。
あと正規表現による絞込みがあります。
 
 
あの日あの時Hashクラスを知っていれば、道は変わっていたかもしれない。
なんて思ってしまいました。
ではまた。

現役ウェブ解析士が教えるWebサイトの読み解き方 イメージ
システム開発サービスはこちら
ページTOPへ