
php 入門者です。よろしくお願いします。
phpでcsvファイルを読み込み、連想配列に代入し、いろいろなキーでソートしたいと考えております。
例えば以下のようなcsvファイルがあるとします。
商品コード,商品名,価格,在庫数
001,りんご,100,5
002,みかん,200,10
003,ぶどう,200,3
004,バナナ,100,10
005,柿,300,5
このデータを、商品コードをキーにした連想配列を作成し、ksortなどでソートさせることはできました。
しかし、価格や在庫数でソートしようと思い、同じようにそれらをキーにした連想配列を作成しソートさせると、キーが重複してしまい、上書きされてしまいます。
そこで質問なのですが、
価格や在庫数でソートし、もし価格や在庫数が同じならば、商品コード順にソートする。
このようなソート方法を教えて下さい。
よろしくお願いします。
No.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のマニュアルには、どんなアルゴリズムを使用しているか明記されていないので、比較順番もわかりません。
たいへんわかりやすく、丁寧な説明ありがとうございます。
sort関数を使わずにソートするプログラムは書いたことがありません。
順を追ってまずそちらを勉強することで理解を深めていこうと思います。
usortの説明も初心者にもわかりやすく、ずいぶん理解できました。
本当にありがとうございます。
今後もphpを独学していくつもりですが、まわりにプログラミングに詳しい人がいないので、
また質問することがあるかもしれませんが、その時はどうぞよろしくお願いします。
No.3
- 回答日時:
ANo.2です。
あまりのことで途中でPOSTしてしまいました(汗>returnされた値はどこでなにをしているのでしょうか?
usortは「ユーザー定義の比較関数により配列をその値でソートします」という仕様なので、「並べ替えに使われます」としか・・・
こう書けば、こう動くということはわかったのですが、
プログラム初心者だからか、理解力が乏しいのか難しいです…
今回の例だと、
始め$aには一つ目のデータ(りんご)の価格が$bには二つ目のデータ(みかん)の価格が代入され、
比較して、大小または同じ場合によってreturnされる値が変わり、
次に$bの値が三つ目のデータ(ぶどう)に変わり比較してretun…
それが終われば四つ目のデータ比較…みたいな感じで繰り返されていくのでしょうか?
それとも、最初はあまり考えずに「そーゆーもん」だと納得して、
いずれ理解できてくるものなんでしょうか?
No.2
- 回答日時:
>マニュアルなどは一応読んでみたのですが、
え?
http://jp.php.net/manual/ja/function.usort.php
----- 引用ここから
比較関数は、最初の引数と二番目の引数の比較結果を返します。最初の引数のほうが二番目の引数より大きい場合は正の数を、二番目の引数と等しい場合はゼロを、そして二番目の引数より小さい場合は負の数を返す必要があります。
----- 引用ここまで
No.1
- 回答日時:
こういうデータの持ち方にしてください
<?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);
早速の回答ありがとうございます。
実際に動かしてみて、満足いく結果は得られたのですが、
書き方が今まで見たことのないもので、
いまいち理解ができておりません。
マニュアルなどは一応読んでみたのですが、
比較して同じなら0、大きければ1、小さければー1をreturnすると言う事ですが、
returnされた値はどこでなにをしているのでしょうか?
よろしければまた回答して頂けると助かります。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語の配列をPush(追加)する...
-
【PHP】配列のキー名の修正は可...
-
cakephpでのトランザクション処...
-
Delphiで別unitで宣言した「TAr...
-
どのような関数名を付けるべき...
-
CArrayのソート
-
プルダウンメニューにDBの内容...
-
PHPのカッコ[ ]の使い方について
-
配列をループでたくさん宣言し...
-
自動で番号を振りたい
-
PHPにてクラスを配列にすること...
-
file_existsでファイル名の部分...
-
String だと「 ByRef引数の型が...
-
マッチング処理(1:N)
-
ネストが深い時のforeachはどう...
-
ftokが動かない?
-
C言語でCSVファイルの行数を読...
-
No.を降順で表示するには
-
foreachとかの勝手な省略?
-
cookieとIPアドレス記録を利用...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語の配列をPush(追加)する...
-
STLのvectorで作った配列をメン...
-
行列
-
CArrayのソート
-
読み(あ行~わ行)ごとに分け...
-
C言語 最大値と最小値を求めて...
-
delphi 2次元配列がわかりません
-
CArrayの要素としてCStringArra...
-
特定の文からメールアドレスの...
-
System.String.Splitでエラー
-
verilogで、配列の一部をタスク...
-
PHPで10連ガチャを作成したいの...
-
再帰関数を用いて配列の合計を...
-
cakephpでのトランザクション処...
-
mb_encode_numericentityでタグ...
-
配列を指定した順序でソート
-
多次元配列をエンコードする関...
-
forとかで連番の変数を一気に格...
-
楽天市場ジャンル検索APIで順番...
-
正規表現
おすすめ情報