usortを使ったphp多次元配列のソートについて

このQ&Aのポイント
  • usortを使ったphpの多次元配列のソート方法について解説します。
  • 例題を使って詳しく説明します。
  • usortとstrcmp関数の働きについて説明します。
回答を見る
  • ベストアンサー

php多次元配列のソート(usort)について

http://www.php.net/manual/ja/function.usort.php にusortの例として下記がありますが、それについて質問です。 -------------例文------------- <?php function cmp($a, $b) { return strcmp($a["fruit"], $b["fruit"]); } $fruits[0]["fruit"] = "lemons"; $fruits[1]["fruit"] = "apples"; $fruits[2]["fruit"] = "grapes"; usort($fruits, "cmp"); while (list($key, $value) = each($fruits)) { echo "\$fruits[$key]: " . $value["fruit"] . "\n"; } ?> -------------結果------------- $fruits[0]: apples $fruits[1]: grapes $fruits[2]: lemons 上の例は、usortで$fruitsという配列をソートしています。 そのとき、cmpという関数を条件にしている、というのは分かりますが、 なぜcmpを条件にすることでアルファベットの昇順になるのでしょうか? strcmp($a["fruit"], $b["fruit"]);にたとえばlemonsとかapplesが入って strcmpによって比較がされて、結果として1や-1が返されて その結果、たとえばusort($fruits, "-1")や、usort($fruits, "1") となったとします。それがなぜ結果として昇順になるのでしょうか?

  • PHP
  • 回答数1
  • ありがとう数0

質問者が選んだベストアンサー

  • ベストアンサー
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

>それがなぜ結果として昇順になるのでしょうか? そうなるような関数だからとしか言いようがないと思いますが・・・ usortの第一引数に配列をいれ、第二引数についてはコールバック関数を指定しいます コールバック関数の第一引数と、第二引数を比較して、大小をチェックして 1か0か-1の戻り値によりソートするというのがusortなので・・・ あとはいろんな例をご自身で確かめて理解する以外ないでしょう

関連するQ&A

  • 連想二次元配列のUNIXTIMEでのソート

    ID(主キー)、unixtime、nameをフィールド名とするとするSQLのデータベースを取得してUNIXTIMEを比較してソートするようなPHPを作りました。   $contents= array(); $temp = mysql_query($query, $link ); while( $contents = mysql_fetch_array($temp, MYSQL_ASSOC)){ } //比較してソート function cmp($a, $b) { print_r($a); if ($a["unixtime"] == $b["unixtime"]) { return 0; } return ((int)$a["unixtime"] < (int)$b["unixtime"]) ? 1 : -1; } usort($contents, "cmp"); しかしこれを実行したところ、 Warning: usort() expects parameter 1 to be array, boolean given in C:\xampp\htdocs\php\outstr.php on line 49 となってしまいます。 usortのエラーのようですが、なぜこうなってしまうのでしょうか。 正常にソートできるような方法を教えてください。

    • ベストアンサー
    • PHP
  • 配列の日付ソート処理2

    先ほど下記のような質問をしたのですが、、、 最初の配列の添え字を取得したい場合はどのようにしたらいいのでしょうか?? ksort($up_date, "cmp"); while (list ($key, $value) = each ($up_date)) { echo "$key: $value\n"; } function cmp ($a, $b) { if ($a == $b) return 0; return ($a > $b) ? -1 : 1; } としても、日付がうまく昇順されません。 この方法では駄目なのでしょうか?? ******************************************* 配列に下記のような日付が入ってます。 $array[0]=2004-11-01 14:20:10.412761+09; $array[1]=2004-11-28 19:09:42.898169+09; $array[2]=2004-11-26 17:16:10.531744+09; $array[3]=2004-11-30 20:25:39.622259+09; これをもっとも新しい日付の順序にしたいのですが、 これはやはり、バブルソートなどを作成する必要がでてきますでしょうか??? *********************************************

    • ベストアンサー
    • PHP
  • PHP 多次元配列のソート

    $array = array( array("address" =>"eeee@dddd.ddd","name" => "あいう"), array("name" => "はざま","address" => "cccc@dddd.ddd"), array("name" => "かきく","address" => "tttt@ccc.eee"), array("name" => "さく","address" => "bbbb@dddd.ddd"), array("name" => "あか","address" => "aaaa@dddd.ddd") ); 上記のような多次元配列があった場合 sort($array); とすると 以下のようなデフォルトの配置が Array ( [0] => Array ( [address] => eeee@dddd.ddd [name] => あいう ) [1] => Array ( [name] => はざま [address] => cccc@dddd.ddd ) [2] => Array ( [name] => かきく [address] => tttt@ccc.eee ) [3] => Array ( [name] => さく [address] => bbbb@dddd.ddd ) [4] => Array ( [name] => あか [address] => aaaa@dddd.ddd ) ) 上記の並びが Array ( [0] => Array ( [address] => eeee@dddd.ddd [name] => あいう ) [1] => Array ( [name] => あか [address] => aaaa@dddd.ddd ) [2] => Array ( [name] => かきく [address] => tttt@ccc.eee ) [3] => Array ( [name] => さく [address] => bbbb@dddd.ddd ) [4] => Array ( [name] => はざま [address] => cccc@dddd.ddd ) ) nameキーの値をもとにあいうえお順にならびかえられます。 がこれをnameキーではなく addressキーで並び替えたいと思ったとき、 usort($array , function($a,$b){ if($a["address"]< $b["address"]){ return -1; }else{ return 1; } } ); と上記のようのおこなうと Array ( [0] => Array ( [name] => あか [address] => aaaa@dddd.ddd ) [1] => Array ( [name] => さく [address] => bbbb@dddd.ddd ) [2] => Array ( [name] => はざま [address] => cccc@dddd.ddd ) [3] => Array ( [address] => eeee@dddd.ddd [name] => あいう ) [4] => Array ( [name] => かきく [address] => tttt@ccc.eee ) ) とうまくaddressキーでabcdの順にソートできています。 次に usort($array , function($a,$b){ return strcmp($a["address"],$b["address"])? -1:1; } ); と上記のようにstrcmp関数を使うと Array ( [0] => Array ( [name] => あか [address] => aaaa@dddd.ddd ) [1] => Array ( [name] => さく [address] => bbbb@dddd.ddd ) [2] => Array ( [name] => かきく [address] => tttt@ccc.eee ) [3] => Array ( [name] => はざま [address] => cccc@dddd.ddd ) [4] => Array ( [address] => eeee@dddd.ddd [name] => あいう ) ) うまくソートできませんでした。 この、直接 $a, $bの大小を条件とした場合と strcmp — バイナリセーフな文字列比較をおこなうstrcmp とは、どのような処理の違いがあるのでしょうか?

    • ベストアンサー
    • PHP
  • usort のユーザー定義比較関数の説明について

    PHPマニュアルにあるusortの説明がうまく理解できなくて悩んでいます。 そこでは、パラメータとなる比較関数について次のように書かれています。 「比較関数は、最初の引数と二番目の引数の比較結果を返します。最初の引数のほうが二番目の引数より大きい場合は正の数を、二番目の引数と等しい場合はゼロを、そして二番目の引数より小さい場合は負の数を返す必要があります。」 http://php.net/manual/ja/function.usort.php 「usort() の例」として提示されているのは以下です。 function cmp($a, $b) { if ($a == $b) { return 0; } return ($a < $b) ? -1 : 1; } $a = array(3, 2, 5, 6, 1); usort($a, "cmp"); この例のユーザー定義の比較関数cmpは、前述の説明の通りに書かれているので理解できます。 しかし、ユーザーページの投稿にもありますが、($a > $b) としたり、($a < $b) ? 1 : -1 のように返り 値を変えて降順(逆順)にソートするという使い方を普通に見かけます。 これは、「最初の引数のほうが二番目の引数より大きい場合は正の数を(……)二番目の引数より小さい場合は負の数を返す必要があ」るという説明とは矛盾しています。 「必要」とまで書いているのでかなり強い指示だと思います。英語版でも「must」となっているので翻訳上の問題はなさそうです。 また、「配列のソート」ページによるとソート順は「ユーザー定義」とあり、件の比較関数次第ということになっています。 http://www.php.net/manual/ja/array.sorting.php ということは、逆順であれ自然順であれ可能だとこれは示唆しているのだと思うのですが、やはり説明部分との矛盾が気になります。 ……どう捉えたらよいのでしょうか?

    • ベストアンサー
    • PHP
  • 【PHP】usort()関数内の引数について

    【PHP】usort()関数内に出てくる関数の引数の意味を教えてください。 usort(ユーザー定義関数) 以下のような配列があります。ここで'score'を小さな順番(昇順)で並べ替えるためにusort()関数を使いたいと思います。 $data= [ ['name' => 'yamada', 'score'=> 80], ['name' => 'suzuki', 'score'=> 60], ['name' => 'tanaka', 'score'=> 70], ['name' => 'okada', 'score'=> 60], ]; usort( $data, function($a, $b){ if ($a['score']=== $b['score']){ return 0; } return $a['score'] > $b['score'] ? 1: -1; } ); echo "<pre>"; print_r($data); echo "</pre>"; ----------------------------------------------------------------- サンプルでは上記のように$a,$bが使用されています。 スコアの数値を比較して、あるスコアの値と別のスコアの値が同じであれば「0」を返す。$aの値が$bより大きければ「1」を返す、そうでなければ「-1」を返す。 返ってきた値、「-1」,「 0」,「 1」と小さな順に並べる… こういうことかと思います。添付画像のように表示された値も合っています。 が、functionの引数($a, $b)の意味がよくわかりません。 foreachなどでループさせ値を一つづつ比較するというよう作業を行うのであればまだ理解できるかもしれませんが、ただ単に引数に function($a, $b)…としただけでscoreの値が$a、$bにどうやって代入されていくのでしょうか?? $a, $bと記述しただけで全てのscoreの値をなぜ比較してくれるのかわかりません。 また、現在$dataの中には4つしか配列がありません。-1,0,1だけで順番をつけられるでしょうが、これが50, 100個と配列データが増えた場合でもこのやり方でできるのでしょうか? 初学者です。分かる方いらっしゃいましたら教えて下さい。よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • 多次元配列のソートについて

    始めまして。 多次元配列のソート方法について分からないことがある為教えていただけないでしょうか。 $a[0] = array('2007/3/1','あ100','その他'); $a[1] = array('2007/3/1','あ200','その他'); $a[2] = array('2007/3/2','あ200','その他'); $a[3] = array('2007/3/2','あ300','その他'); $a[4] = array('2007/3/3','あ50','その他'); 上記のような配列があった場合、usort関数でやると、日付かその後ろの数値の値を元にソートできますが、両者の関係を持たせたソートは可能でしょうか。 結果としては $b[0] = "2007/3/3 あ50"; $b[1] = "2007/3/2 あ200"; $b[2] = "2007/3/2 あ300"; $b[3] = "2007/3/1 あ100"; $b[4] = "2007/3/1 あ200"; というようにしたいのです。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • PHPのusort関数について

    PHPにおけるusort関数およびuasort uksort関数の使い方がわかりません。 $array = array("b" => "bbbb","c" => "cc","d" => "ddddddddddd","e" => "eee","a" => "a","f" => "ffffffff","g" => "gg","h" => "hh"); 上記のような配列があった場合 uasort($array, function($a,$b){ if (strlen($a) == strlen($b)) { return 0; } if(strlen($a) > strlen($b)){ return -1; }else if(strlen($a) < strlen($b)){ return 1; } } ); print_r($array); 上記のようなコードの場合 ( [d] => ddddddddddd [f] => ffffffff [b] => bbbb [e] => eee [h] => hh [g] => gg [c] => cc [a] => a ) という結果がかえてきます。 ただ、実際このコードでなにがおきてるかわかりません。 まず、uasort関数の第二引数に渡す関数の引数 $a,$bはいったいどんな順番で第一引数の配列からわたされているのでしょうか? そして、$a と$ bの値が同じ場合に0を返した場合なにがおきてるのでしょうか? 同じく return 1;を返すときと return -1;を返すときと いったいどのような処理がおこなわれていてどういうなぜ 上記のような配列を返すことになるのでしょうか? そもそも PHPマニュアルから参照しますが 比較関数は、最初の引数と二番目の引数の比較結果を返します。最初の引数のほうが二番目の引数より大きい場合は正の数を、二番目の引数と等しい場合はゼロを、そして二番目の引数より小さい場合は負の数を返す必要があります。 上記説明も、どうにも理解できません。 どうも全体的にusort関数系の使い方がわかりません。 識者の方よろしくご教授いただけますようお願いします。

    • ベストアンサー
    • PHP
  • usortの使い方

    お世話になります。 下記の様なデータが在ります。 ------------------------- | namae | age | hantei | ------------------------- | かんざき | 32 | 1 | ------------------------- | みやざき | 39 | 2 | ------------------------- | あんざき | 26 | 1 | ------------------------- | まえざき | 32 | 1 | ------------------------- | しもざき | 29 | 2 | ------------------------- | あんざき | 26 | 1 | ------------------------- このデータを[namae]で50音順に並び替えることは出来るのですが、[hanntei]でソートさせた後に[namae]でソートしたいです。 上記データが$nameに格納されています。 usortの使い方を教えて下さい。 //優先順位比較 function namecmp($a, $b) { return $a["namae"] > $b["namae"]; } //配列の並べ替え usort($name, "namecmp"); 宜しくお願いします

    • ベストアンサー
    • PHP
  • 2次元配列のソート

    下記3つの2次元配列を個人コードをキーとして昇順に新しい2次元配列Dへ格納する場合、どのようなやり方が最も速く出来るでしょうか? ご教授願います。 出来ればサンプルプログラムなど書いて頂けると非常にありがたいです。 A vntArray(0,0)=001・・・個人ID vntArray(0,1)=aaa・・・個人コード vntArray(0,2)=田中・・・氏名 vntArray(1,0)=005 vntArray(1,1)=eee vntArray(1,2)=中村 B vntArray(0,0)=003 vntArray(0,1)=ccc vntArray(0,2)=菊地 C vntArray(0,0)=002 vntArray(0,1)=bbb vntArray(0,2)=阿部 vntArray(0,0)=004 vntArray(0,1)=ddd vntArray(0,2)=川上

  • MYSQLとPHPによって取得する多次元配列

    はじめてご質問させていただきます。 現在以下のようなテーブルが3つあります。 [ tbl1 ] | tbl1Key | title | | 1 | a | | 2 | b | | 3 | c | | 4 | d | [tbl2] | tbl2Key | tbl1Key | tbl3Key | | 1 | 2 | 2 | | 2 | 3 | 1 | | 3 | 3 | 4 | | 4 | 1 | 3 | [tbl3] | tbl3Key | value | | 1 | aaa | | 2 | bbb | | 3 | ccc | | 4 | ddd | 上記のデータソースを元に以下のような結果を得たいと考えています。 array( array( 'tbl1Key'=>1, 'title'=>'a', 'values' => array( array( 'tbl3Key'=>3, value='ccc' ) ), array( 'tbl1Key'=>2, 'title'=>'b', 'values' => array( array( 'tbl3Key'=>2, value='bbb' ) ), array( 'tbl1Key'=>3, 'title'=>'c', 'values' => array( array( 'tbl3Key'=>1, value='aaa'), array( 'tbl3Key'=>4, value='ddd' ) ), array( 'tbl1Key'=>4, 'title'=>'d', 'values' = > array( array( 'tbl3Key'=> , value='' ) ) ) この場合phpによって $sql = ("select * from `tbl1`"); $res = mysql_query( $sql, $con ); $data = array(); while( $row =mysql_fetch_object( $res ) ) { $sql = ("select * from `tbl3` inner join `tbl2` on `tbl3`.`tbl3Key`=`tbl2`.`tbl3Key` where `tbl2`.`tbl1Key`={$row->tbl1Key}"); $res2 = mysql_query( $sql, $con ); $tmp = array(); while( $r = mysql_fetch_object( $res2 ) ) { $tmp[] = $r->value; } $row->values = $tmp; $data = $row; } まずtbl1のデータをすべて取り、配列dataに格納する段階で、tbl1と関連付けされたtbl3のvalueを取得し配列tblに格納、それを新しい要素として配列dataにプッシュしている状況です。 こういったテーブルでいうところの1カラムのみ配列で返すような事は、こういったループを使って以外にも可能なのでしょうか。 よろしくお願いいたします。

    • 締切済み
    • PHP

専門家に質問してみよう