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を探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【お題】絵本のタイトル
- ・【大喜利】世界最古のコンビニについて知ってる事を教えてください【投稿~10/10(木)】
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・ハマっている「お菓子」を教えて!
- ・最近、いつ泣きましたか?
- ・夏が終わったと感じる瞬間って、どんな時?
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語の配列をPush(追加)する...
-
C言語 最大値と最小値を求めて...
-
行列
-
読み(あ行~わ行)ごとに分け...
-
cakephpでのトランザクション処...
-
pythonのプログラムについて
-
MYSQLとPHPによって取得する多...
-
CSVファイルの最終行のデー...
-
$_SESSIONに二次元配列を使える...
-
【Smarty】foreach関数やsectio...
-
連想配列のキー値(連番)を基...
-
VB.NET で 二次元のハッシュは...
-
Resource id #3 と表示されま...
-
rubyで複数列のデータを一行に...
-
CSVデータの行数カウントをした...
-
PHPでCSVの一部の行を編集したい
-
pdfファイルの複数添付 引数の型
-
PHP 多次元配列変数のデータ受...
-
PHPでテキストファイルの一部を...
-
postgresql関数をつかったレコ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語の配列をPush(追加)する...
-
読み(あ行~わ行)ごとに分け...
-
pg_copy_fromの使い方について...
-
STLのvectorで作った配列をメン...
-
特定の文からメールアドレスの...
-
配列の要素(value)に、変数を...
-
C言語 最大値と最小値を求めて...
-
行列
-
cakephpでのトランザクション処...
-
ファイルの書き込みについて教...
-
Smarty 三次元配列を使いたい
-
Smartyで多次元配列をスマート...
-
verilogで、配列の一部をタスク...
-
fgetc関数について
-
配列の添え字が小数だとどうなる?
-
CArrayのソート
-
変数の一致条件がたくさんある...
-
array_intersectで空欄を比較し...
-
2次元配列への標準入力
-
2次元配列CSVのソート
おすすめ情報