1つだけ過去を変えられるとしたら?

php 入門者です。よろしくお願いします。

phpでcsvファイルを読み込み、連想配列に代入し、いろいろなキーでソートしたいと考えております。
例えば以下のようなcsvファイルがあるとします。

商品コード,商品名,価格,在庫数
001,りんご,100,5
002,みかん,200,10
003,ぶどう,200,3
004,バナナ,100,10
005,柿,300,5

このデータを、商品コードをキーにした連想配列を作成し、ksortなどでソートさせることはできました。

しかし、価格や在庫数でソートしようと思い、同じようにそれらをキーにした連想配列を作成しソートさせると、キーが重複してしまい、上書きされてしまいます。

そこで質問なのですが、
価格や在庫数でソートし、もし価格や在庫数が同じならば、商品コード順にソートする。
このようなソート方法を教えて下さい。

よろしくお願いします。

A 回答 (4件)

入門者、とのことですが


PHPのsort関数等を使わずに、ソートするプログラムを書いたことはありますか?

目的のことをするための「やり方」「手順」を「アルゴリズム」と言います。
http://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%AB% …

ソートのアルゴリズムには、性質の異なるものが沢山あります。
http://ja.wikipedia.org/wiki/%E3%82%BD%E3%83%BC% …
ソートの解説は、書籍、サイト等でも詳しく説明されています。
「PHP ソート アルゴリズム」で検索すれば、PHPで記述したプログラムもみつかります。
これらを元にして、自作したり、コピーしたりして、実際に動かしてみるとよいでしょう。

単純な数値の比較の場合は、<や>で比較できます。
ですが、今回は、配列同士の比較になります。
array("商品コード"=>"001","商品名"=>"りんご","価格"=>100,"在庫数"=>5)

array("商品コード"=>"002","商品名"=>"みかん","価格"=>200,"在庫数"=>10)
のどちらが「大きい」かを決めなければなりません。そこで、usortでは、比較関数を使います。

通常の数値では
if( $x[$i] < $x[$j] ) ~
等と不等号で比較するところを
if( cmp_functon($x[$i], $x[$j]) < 0 ) ~
等と比較関数を使用するわけです。


> 始め$aには一つ目のデータ(りんご)の価格が$bには二つ目のデータ(みかん)の価格が代入され、
> 比較して、大小または同じ場合によってreturnされる値が変わり、
> 次に$bの値が三つ目のデータ(ぶどう)に変わり比較してretun…
> それが終われば四つ目のデータ比較…みたいな感じで繰り返されていくのでしょうか?

$a,$bはソートする配列の2つ要素です。例えば
$a : array("商品コード"=>"001","商品名"=>"りんご","価格"=>100,"在庫数"=>5)
$b : array("商品コード"=>"002","商品名"=>"みかん","価格"=>200,"在庫数"=>10)
等です。
「データの価格」が直接入るのではありません。
価格でソートしたいので、 $a["価格"]と$b["価格"]の比較結果で戻り値を決定しています。

・どういう順番で比較しているか、は、使われるアルゴリズムによります。
usortのマニュアルには、どんなアルゴリズムを使用しているか明記されていないので、比較順番もわかりません。
    • good
    • 0
この回答へのお礼

たいへんわかりやすく、丁寧な説明ありがとうございます。

sort関数を使わずにソートするプログラムは書いたことがありません。
順を追ってまずそちらを勉強することで理解を深めていこうと思います。

usortの説明も初心者にもわかりやすく、ずいぶん理解できました。

本当にありがとうございます。

今後もphpを独学していくつもりですが、まわりにプログラミングに詳しい人がいないので、
また質問することがあるかもしれませんが、その時はどうぞよろしくお願いします。

お礼日時:2012/10/08 14:46

ANo.2です。

あまりのことで途中でPOSTしてしまいました(汗

>returnされた値はどこでなにをしているのでしょうか?

usortは「ユーザー定義の比較関数により配列をその値でソートします」という仕様なので、「並べ替えに使われます」としか・・・
    • good
    • 0
この回答へのお礼

こう書けば、こう動くということはわかったのですが、
プログラム初心者だからか、理解力が乏しいのか難しいです…

今回の例だと、
始め$aには一つ目のデータ(りんご)の価格が$bには二つ目のデータ(みかん)の価格が代入され、
比較して、大小または同じ場合によってreturnされる値が変わり、
次に$bの値が三つ目のデータ(ぶどう)に変わり比較してretun…
それが終われば四つ目のデータ比較…みたいな感じで繰り返されていくのでしょうか?

それとも、最初はあまり考えずに「そーゆーもん」だと納得して、
いずれ理解できてくるものなんでしょうか?

お礼日時:2012/10/08 01:34

>マニュアルなどは一応読んでみたのですが、



え?

http://jp.php.net/manual/ja/function.usort.php
----- 引用ここから
比較関数は、最初の引数と二番目の引数の比較結果を返します。最初の引数のほうが二番目の引数より大きい場合は正の数を、二番目の引数と等しい場合はゼロを、そして二番目の引数より小さい場合は負の数を返す必要があります。
----- 引用ここまで
    • good
    • 0

こういうデータの持ち方にしてください



<?PHP
$a=array(
array("商品コード"=>"001","商品名"=>"りんご","価格"=>100,"在庫数"=>5),
array("商品コード"=>"002","商品名"=>"みかん","価格"=>200,"在庫数"=>10),
array("商品コード"=>"003","商品名"=>"ぶどう","価格"=>200,"在庫数"=>3),
array("商品コード"=>"004","商品名"=>"バナナ","価格"=>100,"在庫数"=>10),
array("商品コード"=>"005","商品名"=>"柿" ,"価格"=>300,"在庫数"=>5)
);
function mysort($a,$b){
if($a["価格"]==$b["価格"]) return 0;
return $a["価格"]>$b["価格"] ?-1:1;
}

usort($a,"mysort");
print_r($a);
    • good
    • 0
この回答へのお礼

早速の回答ありがとうございます。

実際に動かしてみて、満足いく結果は得られたのですが、
書き方が今まで見たことのないもので、
いまいち理解ができておりません。

マニュアルなどは一応読んでみたのですが、
比較して同じなら0、大きければ1、小さければー1をreturnすると言う事ですが、
returnされた値はどこでなにをしているのでしょうか?

よろしければまた回答して頂けると助かります。

お礼日時:2012/10/07 22:36

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!