【PHP】多次元配列をあるキーを基準に並び替えたい

php

ある案件で画像のパス、タイトル、カテゴリ、リンク先などのデータを多次元配列で管理していて、カテゴリ事に並び替える必要性があったんですが、分からなくて調べてみました。そしたら「array_multisort」が使えそうだったので調査してみました。

普通の配列で並び替えをしてみる

「array_multisort」は複数の配列を一度に処理したり、多次元配列をある次元の値を元にソートできるようです。またソートする場合、配列のインデックスのキーの相関は維持されるようです。

試しに2つの配列を処理してみます。


動作結果(単純な実験のほうをクリック)

上記の例をみていただくとわかると思うが、ar1が「100,60,20,10」の順番(降順)になっていると思うが、ar2が「3,2,4,1」という順番になっている。
これはソートして並び替えられたar1の配列のインデックスのキーとar2のキーが紐づいているようです。例えばar1「3」番目のキーの値の20がソートによってar「2」になった場合ar2「3」番目のキーの4もar2「3」になる・・という具合です。
動作結果を見ていただくと分かると思うが、常に位置関係が同じです。

多次元配列の特定のキーで並び変える

上記で記述したように、arraymultisortでキーの相関を維持するとのことで、多次元配列の特定のキーに並び替えることができそうです。

下記の例ではage(年齢)を基準に並びかえてみる


//多次元配列を作る
$multiArray=array(
            "list1"=>array("name"=>"石山","age"=>20,"english"=>"a"),
            "list2"=>array("name"=>"山田","age"=>21,"english"=>"f"),
            "list3"=>array("name"=>"田中","age"=>4, "english"=>"g"),
            "list4"=>array("name"=>"佐藤","age"=>23,"english"=>"d"),
            "list5"=>array("name"=>"宮下","age"=>50,"english"=>"c"),
            "list6"=>array("name"=>"鈴木","age"=>45,"english"=>"e"),
            "list7"=>array("name"=>"加藤","age"=>14,"english"=>"b")
        );

//foreachでageの値を配列$ageに取り出す。
foreach($multiArray as $key=>$value){
            $age[$key]=$value["age"];    
        }
//配列$ageを並び替える、それに伴って$multilArrayも並び替える
array_multisort($age,SORT_ASC,$multiArray);

動作結果(多重配列の処理のほうをクリック)
動作結果を見ていただくと分かると思いますが、ageを基準に並びかえると多次元配列のデータが入れ替わっているのが分かると思います。

  • 1:まずはforeach文でageのキーを持つ値を別の配列に抜き取る。
  • 2:array_multisortで年齢順にソートで並び替え、$multiArrayも$ageのキーに紐づいてるので並び変わる

といった具合に便利でした。まぁ今回はシンプルな方でもすこし複雑な処理もできそうですが、おいおい。

注意点

array_multisortを試している最中に気が付いた点。ageで並び替えて試してみて、englishのキーでも並びかえてみようとおもって下記のような記述をしました。

$multiArray=array(
            "list1"=>array("name"=>"石山","age"=>20,"english"=>"a"),
            "list2"=>array("name"=>"山田","age"=>21,"english"=>"f"),
            "list3"=>array("name"=>"田中","age"=>4, "english"=>"g"),
            "list4"=>array("name"=>"佐藤","age"=>23,"english"=>"d"),
            "list5"=>array("name"=>"宮下","age"=>50,"english"=>"c"),
            "list6"=>array("name"=>"鈴木","age"=>45,"english"=>"e"),
            "list7"=>array("name"=>"加藤","age"=>14,"english"=>"b")
        );
//
 foreach($multiArray as $key=>$value){
            $age[$key]=$value["age"];
            $eng[$key]=$value["english"];      
        }
//
array_multisort($age,SORT_ASC,$multiArray);
array_multisort($eng,SORT_STRING,$multiArray);

見てのとおり、array_multisortで$multiArrayのデータを連続で並び替えてます。そうすると、どうやら先に$ageで並び替えられてその後に、$engで並び替えられるようなのでもし$engのみで並び代えたい場合は別の配列名にするなど注意が必要です。

参考になったサイト

QUALL 多次元配列のソート(array_multisort)について[PHP]