array_multisort で キー値を保持しつつソートする 3

array_multisort で キー値を保持しつつソートする

ArrayベースのDBを作って、使ってるわけですが、
そういう稀有な場合、array_multisort君がキー値を捨ててしまうのが
非常に邪魔なので、それをなんとか保持できないかという方法。

array_multisort

//今回のテストデータ

$mainData = array();
$mainData[] = array('data'=>'green33','main'=>'red33');
$mainData[] = array('data'=>'green40','main'=>'red40');
$mainData[] = array('data'=>'green31','main'=>'red31');
$mainData[] = array('data'=>'green10','main'=>'red10');
$mainData[] = array('data'=>'green20','main'=>'red20');
$mainData[] = array('data'=>'green30','main'=>'red30');


普通にやるとこう

$search = array();
foreach ($mainData as $v) $search[] = $v['main'];
array_multisort($search,$mainData);
print_r($mainData);

Array
(
    [0] => Array
        (
            [data] => green10
            [main] => red10
        )

    [1] => Array
        (
            [data] => green20
            [main] => red20
        )

    [2] => Array
        (
            [data] => green30
            [main] => red30
        )
-略-
)

で どうするかというと、
array_multisort君が捨てるキーは数値添字のみなので、
数値添字をstringに変えてしまう(型キャストだけだと、自動変換でINTに戻っちゃう)

ってことでこうする
//キーを取得してすべて文字列にして元の配列に戻す
$keyData = array_keys($mainData);
array_walk($keyData,create_function('&$i,$k','$i .= "_";'));
$keyFixedData = array_combine($keyData,$mainData);


//それをarray_multisort
$search = array();
foreach ($mainData as $v) $search[] = $v['main'];
array_multisort($search,$keyFixedData);


//またキーを全部取得して最初の添字に戻す
$keyData = array_keys($keyFixedData);
array_walk($keyData,create_function('&$i,$k','$t = split("_",$i);$i = $t[0];'));
$result = array_combine($keyData,$keyFixedData);


//中間データはこんな感じになる
print_r($keyFixedData);
Array
(
    [3_] => Array
        (
            [data] => green10
            [main] => red10
        )

    [4_] => Array
        (
            [data] => green20
            [main] => red20
        )

    [5_] => Array
        (
            [data] => green30
            [main] => red30
        )
-略-
)


//完成データ
print_r($result);
Array
(
    [3] => Array
        (
            [data] => green10
            [main] => red10
        )

    [4] => Array
        (
            [data] => green20
            [main] => red20
        )

    [5] => Array
        (
            [data] => green30
            [main] => red30
        )
-略-
)

ってなって最終的にキーを保持したarray_multisortが可能になるというわけです。

結論

arrayベースのDBはやめましょう

3 thoughts on “array_multisort で キー値を保持しつつソートする

  1. Reply CertaiN 8月 24,2013 7:36 AM

    古い記事にコメント失礼します(今後の訪問者のためにも)
    uasort()関数使えば一発ですね。

    <?php
    uasort($mainData, function ($a, $b) { return strcmp($a['main'], $b['main']); });

  2. Reply Jakk 8月 27,2013 10:31 AM

    コメントありがとうございます。
    古い記事とはいえ、恥ずかしながら今でも知らなかったので、勉強になりました。
    ありがとうございます!

  3. Reply Kim 12月 25,2014 12:06 PM

    助かりました!

Leave a Reply