LoginSignup
12
11

More than 5 years have passed since last update.

array_unique_callback 的な何か

Last updated at Posted at 2013-11-29

array_unique

配列を渡すだけで重複している要素を削除してくれるとっても便利な関数です。しかし、値が文字列にキャスト可能な1次元の配列にしか適用できないという制約があります。これをカスタムするための関数を作ってみましょう。

array_unique_callback

array_filterstatic変数 と絡めて使用するのがネックです。

function array_unique_callback(array $array, callable $callback, $strict = false) {
    return array_filter(
        $array,
        function ($item) use ($callback, $strict) {
            static $h = array();
            $r = !in_array($n = $callback($item), $h, $strict) and $h[] = $n;
            return $r;
        }
    );
}
  • PHPにありそうな感じの名前にしました。
  • PHP5.3では callable タイプヒンティングを外してください。
  • isset を用いて $O(1)$ の探索時間を実現しても良かったのですが、今回はスカラー値以外も比較に使用できるように in_array を使う実装にしました。

下に使用例を示します。

PHPコード
<?php

$companies = array(
    0 => array(
        'name' => 'やずや',
        'phone' => '0120-828-828',
        'category' => 'サプリメント',
    ),
    1 => array(
        'name' => 'DHC',
        'phone' => '0120-575-3709',
        'category' => 'サプリメント',
    ),
    2 => array(
        'name' => 'KIRIN',
        'phone' => '0120-111-560',
        'category' => 'お酒',
    ),
);

$companies = array_unique_callback(
    $companies,
    function ($company) {
        return $company['category'];
    }
);

print_r($companies);
実行結果
Array
(
    [0] => Array
        (
            [name] => やずや
            [phone] => 0120-828-828
            [category] => サプリメント
        )

    [2] => Array
        (
            [name] => KIRIN
            [phone] => 0120-111-560
            [category] => お酒
        )

)

作ってみたものの・・・

ぶっちゃけこれぐらい関数化しなくても普通にシンプルに書けるからいらないかも・・・w
連想配列のキーに格納する方法だと、代入式

$h[$c['category']] = true

が必ず TRUE と評価されるのでここまで短く書ける。

$companies = array_filter(
    $companies,
    function ($c) {
        static $h;
        return !isset($h[$c['category']]) and $h[$c['category']] = true;
    }
);
12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11