LoginSignup
1
1

More than 3 years have passed since last update.

array_multisortでソートができなかった話

Posted at

はじめに

array_multisortで引っかかったので備忘録として書きました

動作確認環境

OS PHP version
Windows 10 7.2.11

確認データ

以下の配列データをranking列の値が低い順にソートします

weather ranking
晴れ 2
3
曇り 1

ソートしてみる

正しい使い方

まずは正しい使い方を記載します

<?php

// ソート対象
$sort_data = array();
array_push($sort_data, ['weather' => '晴れ', 'ranking' => 2]);
array_push($sort_data, ['weather' => '雨', 'ranking' => 3]);
array_push($sort_data, ['weather' => '曇り', 'ranking' => 1]);

// ソートするキーを設定
$target_keys = array();
foreach ($sort_data as $k => $v)  $target_keys[$k] = $v['ranking'];

// ソート前のデータを出力
print_r("ソート前\n");
print_r($sort_data);

// 昇順ソート
array_multisort($target_keys, SORT_ASC, $sort_data, SORT_NUMERIC);

// ソート後のデータを出力
print_r("ソート後\n");
print_r($sort_data);

結果は以下となります

ソート前
Array
(
    [0] => Array
        (
            [weather] => 晴れ
            [ranking] => 2
        )

    [1] => Array
        (
            [weather] => 雨
            [ranking] => 3
        )

    [2] => Array
        (
            [weather] => 曇り
            [ranking] => 1
        )

)
ソート後
Array
(
    [0] => Array
        (
            [weather] => 曇り
            [ranking] => 1
        )

    [1] => Array
        (
            [weather] => 晴れ
            [ranking] => 2
        )

    [2] => Array
        (
            [weather] => 雨
            [ranking] => 3
        )

)

正しくソートされていますね

間違った使い方

間違った使い方です

<?php

// ソート対象
$sort_data = array();
array_push($sort_data, ['weather' => '晴れ', 'ranking' => 2]);
array_push($sort_data, ['weather' => '雨', 'ranking' => 3]);
array_push($sort_data, ['weather' => '曇り', 'ranking' => 1]);

// ソートするキーを設定
$target_keys = array();
foreach ($sort_data as $k => $v)  $target_keys[$k] = $v->ranking;

// ソート前のデータを出力
print_r("ソート前\n");
print_r($sort_data);

// 昇順ソート
array_multisort($target_keys, SORT_ASC, $sort_data, SORT_NUMERIC);

// ソート後のデータを出力
print_r("ソート後\n");
print_r($sort_data);

結果は以下となります

ソート前
Array
(
    [0] => Array
        (
            [weather] => 晴れ
            [ranking] => 2
        )

    [1] => Array
        (
            [weather] => 雨
            [ranking] => 3
        )

    [2] => Array
        (
            [weather] => 曇り
            [ranking] => 1
        )

)
ソート後
Array
(
    [0] => Array
        (
            [weather] => 晴れ
            [ranking] => 2
        )

    [1] => Array
        (
            [weather] => 雨
            [ranking] => 3
        )

    [2] => Array
        (
            [weather] => 曇り
            [ranking] => 1
        )

)

ソートされませんね

原因

単純にキーの設定でアロー演算子を使っているのが原因

foreach ($sort_data as $k => $v)  $target_keys[$k] = $v->ranking;

対象データは連想配列であるためアロー演算子ではとってこれない
実際に$target_keysの値を見てみると空が入っている

Array
(
    [0] =>
    [1] =>
    [2] =>
)

アロー演算子でとってくる場合、対象データ以下のように変更する必要がある

<?php

// ソート対象
$sort_data = array();
$data1 = new \stdClass();
$data1->weather = '晴れ';
$data1->ranking = 2;

$data2 = new \stdClass();
$data2->weather = '雨';
$data2->ranking = 3;

$data3 = new \stdClass();
$data3->weather = '曇り';
$data3->ranking = 1;

array_push($sort_data, $data1);
array_push($sort_data, $data2);
array_push($sort_data, $data3);

// array_push($sort_data, ['weather' => '晴れ', 'ranking' => 2]);
// array_push($sort_data, ['weather' => '雨', 'ranking' => 3]);
// array_push($sort_data, ['weather' => '曇り', 'ranking' => 1]);

// ソートするキーを設定
$target_keys = array();
foreach ($sort_data as $k => $v)  $target_keys[$k] = $v->ranking;

// ソート前のデータを出力
print_r("ソート前\n");
print_r($sort_data);

// 昇順ソート
array_multisort($target_keys, SORT_ASC, $sort_data, SORT_NUMERIC);

// ソート後のデータを出力
print_r("ソート後\n");
print_r($sort_data);

オブジェクトに入れたものならば大丈夫。当たり前ですね。

NOTICEエラーを出すようにしよう

初歩的なミスですが、NOTICEエラー非表示で開発していたためこのエラー出力されず30分画面とにらめっこしてました...
NOTICEエラーを出すと以下のようなエラーが出力されます

PHP Notice:  Trying to get property 'ranking' of non-object in C:\Users\work\test\test.php on line 11

Notice: Trying to get property 'ranking' of non-object in C:\Users\work\test\test.php on line 11
PHP Notice:  Trying to get property 'ranking' of non-object in C:\Users\work\test\test.php on line 11

Notice: Trying to get property 'ranking' of non-object in C:\Users\work\test\test.php on line 11
PHP Notice:  Trying to get property 'ranking' of non-object in C:\Users\work\test\test.php on line 11

Notice: Trying to get property 'ranking' of non-object in C:\Users\work\test\test.php on line 11

開発時はNOTICEエラーを出力するようにしよう...

1
1
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
1
1