• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:配列から順位を算出したい)

配列から順位を算出する方法とは?

このQ&Aのポイント
  • MySqlから配列を取得し、各店舗ごとに製品の順位を算出したいです。
  • 製品ごとに安い順に並び替え、順位を付ける方法を教えてください。
  • CakePHPを使用しています。ご教示いただければ幸いです。

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

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

おなじ価格があった場合順位をどうしたいかにもよりますね 命題の通りやる場合は、製品ごとにソートしてみれば ざっくりとした順位付けができそうですが・・・ たとえばこんな感じ? <?PHP $arr[0]["kihon"]["shop_name"] = "A社"; $arr[0]["kihon"]["shop_category"] = 1; $arr[0]["kakaku"]["seihin_A"] = 1500; $arr[0]["kakaku"]["seihin_B"] = 21580; $arr[0]["kakaku"]["seihin_C"] = 400; $arr[0]["kakaku"]["seihin_D"] = 55000; $arr[1]["kihon"]["shop_name"] = "B社"; $arr[1]["kihon"]["shop_category"] = 1; $arr[1]["kakaku"]["seihin_A"] = 0; $arr[1]["kakaku"]["seihin_B"] = 18580; $arr[1]["kakaku"]["seihin_C"] = 500; $arr[1]["kakaku"]["seihin_D"] = 54800; $arr[2]["kihon"]["shop_name"] = "C社"; $arr[2]["kihon"]["shop_category"] = 2; $arr[2]["kakaku"]["seihin_A"] = 1600; $arr[2]["kakaku"]["seihin_B"] = 17000; $arr[2]["kakaku"]["seihin_C"] = 0; $arr[2]["kakaku"]["seihin_D"] = 65000; $temp_array=array(); foreach($arr as $array){ foreach($array["kakaku"] as $key => $val){ if($array["kakaku"][$key] !=0){ $temp_array[$key][]=array("kakaku"=>$val,"shop_name"=>$array["kihon"]["shop_name"]); } } } foreach(array_keys($temp_array) as $key){ usort($temp_array[$key],"mysort"); } $rank=array(); foreach($temp_array as $key1=>$array1){ foreach($array1 as $key2=>$array2){ $rank[$array2["shop_name"]][$key1]=$key2+1; } } function mysort($a,$b){ if($a["kakaku"]==$b["kakaku"]) return 0; return $a["kakaku"]>$b["kakaku"]; } $str="C社"; foreach($rank[$str] as $product=>$rank){ print $product.":".$rank."<br>"; } ?>

misoshio
質問者

お礼

ご回答ありがとうございます。 簡単に思い通りの結果になりました。 ソース見せてもらうと納得できるのですが、自分にはまだ難しくて書けないですね。とても勉強になります。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

回答No.3

仮にテーブル定義が次のようだとし、 CREATE TABLE shop ( id int NOT NULL auto_increment, name varchar(10), cat int, seihina int, seihinb int, seihinc int, seihind int, PRIMARY KEY (id) ); 格納されているデータが次のようだとしたら、 id name cat seihina seihinb seihinc seihind 1 Asya 1 1500 21580 400 55000 2 Bsya 1 0 18580 500 54800 3 Csya 2 1600 17000 0 65000 次のようなクエリで、 SELECT s1.id, s1.name, s1.seihina, (SELECT count( s2.seihina ) FROM shop s2 WHERE s2.seihina > 0 and s2.seihina < s1.seihina) +1 juna, s1.seihinb, (SELECT count( s2.seihinb ) FROM shop s2 WHERE s2.seihinb > 0 and s2.seihinb < s1.seihinb) +1 junb, s1.seihinc, (SELECT count( s2.seihinc ) FROM shop s2 WHERE s2.seihinc > 0 and s2.seihinc < s1.seihinc) +1 junc, s1.seihind, (SELECT count( s2.seihind ) FROM shop s2 WHERE s2.seihind > 0 and s2.seihind < s1.seihind) +1 jund FROM shop s1 次のような結果が出ます。 id name seihina juna seihinb junb seihinc junc seihind jund 1 Asya 1500 2 21580 1 400 2 55000 2 2 Bsya 0 3 18580 2 500 1 54800 3 3 Csya 1600 1 17000 3 0 3 65000 1 誰かの参考になれば。 会社数が増減し、製品種類も増減するなら、ちょっと面倒かも。

misoshio
質問者

お礼

ご回答ありがとうございます。 CakePHPなのでバーチャルフィールドを使うことも検討したのですが、おっしゃる通り会社や製品名が増減したときに大変なんですよね。 今回私が考えているものは、項目の増減を前提としているのでSQLではデータを全て吐き出させるようにしました。出力する項目が増えてきたらリミットを設けてしのごうと思っています。

全文を見る
すると、全ての回答が全文表示されます。
  • shimix
  • ベストアンサー率54% (865/1590)
回答No.2

usortを使うといいのではないでしょうか? http://jp.php.net/manual/ja/function.usort.php とりあえず同額だったら同順位にするという仕様で書いて見ました。叩き台くらいにはなると思います。 (e.g.) <?php $arr = array(); $arr[] = array('kihon'=>array('shop_name'=>'A社', 'shop_category'=>1), 'kakaku'=>array('seihin_A'=>1500, 'seihin_B'=>21580, 'seihin_C'=>400, 'seihin_D'=>55000)); $arr[] = array('kihon'=>array('shop_name'=>'B社', 'shop_category'=>1), 'kakaku'=>array('seihin_A'=>0, 'seihin_B'=>18580, 'seihin_C'=>500, 'seihin_D'=>54800)); $arr[] = array('kihon'=>array('shop_name'=>'C社', 'shop_category'=>2), 'kakaku'=>array('seihin_A'=>1600, 'seihin_B'=>17000, 'seihin_C'=>0, 'seihin_D'=>65000)); $arr[] = array('kihon'=>array('shop_name'=>'D社', 'shop_category'=>1), 'kakaku'=>array('seihin_A'=>1500, 'seihin_B'=>21580, 'seihin_C'=>400, 'seihin_D'=>55000)); usort($arr, 'sort_seihin_a') or die('sort abort'); $cnt = 0; foreach ($arr as $item) { $cnt++; if ((!isset($sv))or($item['kakaku']['seihin_A'] !== $sv)) { $no = $cnt; } print $no . ':' . $item['kihon']['shop_name'] . ':' . $item['kakaku']['seihin_A'] . '<br />'; $sv = $item['kakaku']['seihin_A']; } function sort_seihin_a($ar1, $ar2) { if ($ar1['kakaku']['seihin_A'] == $ar2['kakaku']['seihin_A']) { return 0; } return ($ar1['kakaku']['seihin_A'] < $ar2['kakaku']['seihin_A']) ? -1 : 1; }

misoshio
質問者

お礼

ご回答ありがとうございます。 同じ値だった場合の順位付けは複雑になるので難しいですね。ご教示くださったソースを参考にさせていただきます。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 多次元配列を、1次元の配列にする関数を書いてください。

    以下のように、多次元配列の配列をペチャンコにする関数(array_flatten)ってどうかきますか? <?php $arr[0] = 'a'; $arr[1][0] = 'b'; $arr[1][1][0] = 'c'; $arr[1][1][1][0] = 'd'; $arr[1][1][1][1][0] = 'e'; $arr[1][1][1][2] = 'f'; $arr[1][1][2] = 'g'; $arr[1][2] = 'h'; $arr[2] = 'i'; function array_flatten($arg){   処理; } $new_arr = array_flatten($arr); print_r($new_arr); ?> ↓ Array (   [0] => a   [1] => b   [2] => c   [3] => d   [4] => e   [5] => f   [6] => g   [7] => h   [8] => i ) ※関数のなかで、ペチャンコの配列を格納するための新しい配列を宣言すると、 同関数を再帰的に呼び出したら、その配列が初期化されますよね?

    • ベストアンサー
    • PHP
  • 多次元配列のキーをつないで文字列にする

    PHP5.4の配列で仮に次のようなものがあったとします。 <?php $arr['A']['B']['C']['D'] = null; $arr['A']['B']['D']['C'] = null; $arr['A']['B']['D'] = null; それぞれのキー名をつなぎあわせてそれぞれ「A, B, C, D」「A, B, D, C」「A, B, D」といった文字列に変換したいのですが、どのようにしたら実現できるのでしょうか? よろしくお願いします。

    • ベストアンサー
    • PHP
  • 多次元配列の扱い方

    PHPバージョン5.2.4を使っています。 次のような文字列が入っている多次元配列を foreachなどのループを使ってその値を取り出して扱いたいのですが、 取り出した値には配列(二次元以降の値)も含まれてるので 簡単には取り扱いできません・・・ print_rやvar_dumpを使えば値は全て表示されるのですが、 あくまで表示ではなくて値を取り扱いたいのです。 そのようなことができる関数などはあるのでしょうか? $arr[0][0] = 'a'; $arr[0][1] = 'b'; $arr[1] = 'c'; $arr[2][0][0][0] = 'd'; $arr[2][0][0][1] = 'e'; foreach ($arr as $value) { $value//←ここで値を扱いたいけど、配列も含まれてるので・・・ }

    • 締切済み
    • PHP
  • 3つの連想配列を交互に代入して、新しい連想配列を作りたい

    PHP Version 5.1.6を使っています。 それぞれの連想配列を先頭から順番に交互に代入したいのですが、 どのようなプログラムでできるのでしょうか? $arr1 = array(a1=>"aa1", a2=>"aa2", a3=>"aa3"); $arr2 = array(b1=>"bb1", b2=>"bb2", b3=>"bb3"); $arr3 = array(c1=>"cc1", c2=>"cc2", c3=>"cc3"); 代入後 $new_arr = array(  a1=>"aa1",  b1=>"bb1",  c1=>"cc1",  a2=>"aa2",  b2=>"bb2",  c2=>"cc2",  a3=>"aa3",  b3=>"bb3",  c3=>"cc3", );

    • ベストアンサー
    • PHP
  • 配列の連想配列のソート

    お世話になります。mooTaihenです。 Perlで配列のソートが出来なくて困っております。 お忙しいところ、誠に申し訳けありませんが、ご教示をお願い致します。 【内容】  サンプルソースに示した様なデータ構成をソートしたいのですが、思惑通りに行きません。  期待しているソート結果は、 a1 b3 b4 c2  です。  <サンプルソース> my @data; $data[0]{name} = "b"; $data[0]{cnt} = 4; $data[1]{name} = "c"; $data[1]{cnt} = 2; $data[2]{name} = "b"; $data[2]{cnt} = 3; $data[3]{name} = "a"; $data[3]{cnt} = 1; @data2 = sort {chg($a,$b)} @data; foreach (@data2) { print $_->{name} . $_->{cnt} . "\n"; } sub chg { my(@s,@d)=@_; return $s[0]{name} cmp $d[0]{name} and $s[0]{cnt} <=> $d[0]{cnt}; }  <出力結果> a1 b3 c2 b4

    • ベストアンサー
    • Perl
  • 割り切れなくなるまで分割して配列に入れたい

    <?php make(7); function make($n) { $arr = array($n); $arr_new = division_arr($arr); print_r($arr_new); } function division_arr($arr) { for ($i = 0; $i < count($arr); $i++) { $arr_new[$i] = division($arr[$i]); if ($arr_new[$i][0] > 0) { return division_arr($arr_new[$i]); } else { } } return $arr_new; } function division($n) { $a = $b = floor($n / 2); if ($n % 2 != 0) { $b+=1; } return array($a, $b); } /* array( [3,4], [[1,2],[2,2]], [[0,1],[1,1],[1,1],[1,1]] ); 再帰的に配列を分割していき、最終的にこのような出力にしたいです。 */ ?> 教えて下さい。よろしくお願いいたします。m(_ _)m

    • ベストアンサー
    • PHP
  • 連想配列でキーを利用して一部分を引き抜きたい

    PHP5.2.4を使用しています。 配列で一部分を引き抜く関数は次のようなarray_spliceで、 $arr = array('a' => 1, 'b' => 2, 'c' => 3); $arr2 = array_splice($arr, 1/*←ここに'b'と書きたい*/, 1); print_r($arr2);//←Array ( [b] => 2 ) print_r($arr);//Array ( [a] => 1 [c] => 3 ) これは第2引数に添え字の番号(上の例だと1)を指定しなければいけないのですが、 そうではなくて、キー('a'や'b'など)を指定して引き抜きたいです。 そのような関数などはあるのでしょうか?

    • ベストアンサー
    • PHP
  • 参照変数の親配列を取得

    データの多次元配列があって、値に応じて動的に関数を選択し 中身の値を引数で渡すみたいな感じの処理をしています ほとんどの処理は中身の値だけあれば事足りるのですが 稀にキー値を使いたい処理がでてきます 本当に稀なので引数にキー値も渡すようにするのは 無駄が多くなるように思うので避けたく できれば参照変数で渡される値から 親配列でのキー値を取得したいと思っています $arr2A=array('a'=>array('fnc'=>'A','あ','い','う'),'b'=>array('fnc'=>'B','か','き','く'),'c'=>array('fnc'=>'C','さ','し','す')); $arr2B=array('a'=>array('fnc'=>'A','あ','い','う'),'b'=>array('fnc'=>'B','か','き','く'),'c'=>array('fnc'=>'C','さ','し','す')); $arr2C=array('a'=>array('fnc'=>'A','あ','い','う'),'b'=>array('fnc'=>'B','か','き','く'),'c'=>array('fnc'=>'C','さ','し','す')); foreach($arr2A as $key=>$val){ $fncs[$val['fnc']]($val); } foreach($arr2B as $key=>$val){ $fncs[$val['fnc']]($val); } foreach($arr2C as $key=>$val){ $fncs[$val['fnc']]($val); } $fncs=array( A=>function(&$arr){ }, B=>function(&$arr){ }, C=>function(&$arr){ //ここで稀にキー値も使いたい }); 実際のコードはかなり長いので載せられませんが 要約すると上記のような感じの処理です まずどのデータ配列の集合から渡されたのかが明確ではありませんので indexOfなどでキー値を得るのというのが難しいです 現在は、その処理が必要なデータ行について処理前に 中身にキー値をあらかじめ入れてしまう というように対応しているので、一応解決はしているのですが もし参照変数から親配列を得る方法が あればと思い質問させていただきました ”そんなものはない”という回答も あきらめつくのでお願いします

    • ベストアンサー
    • PHP
  • 配列について

    配列を使って以下の図のような事をやりたいのですが C言語についてはまだまだ未熟なので教えて頂きたいです。 (サイトなどを回ったのですが良く分かりません) 何をしたいか↓ aという配列に、初期に名前・評価A~D・総合評価項目をいれておく ようにするにはどうしたらいいのか。(配列は1次元) 図 配列a |-------------------------------------| |名前|評価A|評価B|評価C|評価D|総合評価| ↑はこれは出力した場合の結果(printf) printf("|%s|%s|%s|%s|%s|%s|",&a[0], &a[1],&a[2],&a[3],&a[4],&a[5],&a[5]) 自分の考え char a[6]={"従業員名","評価A","評価B","評価C","評価D","総合評価"} ''で囲んだものは文字数を表示させる時に使用 ""で囲んだものは文字列で表示させる時に使用 ※間違っていたら指摘お願いします。

  • 配列のソート

    下記のような形でデータを取得し結果を配列に格納し、 降順にソートしたいのですが、いい方法が見つかりません。いい方法はあるでしょうか。よろしくお願いします。 テーブル構造(test) ID|name |point|area| ==================== 1 |Aさん|56 | A | 2 |Bさん|12 | B | 3 |Cさん|24 | B | 4 |Dさん|34 | B | $sql = "select * from test"; $result = mysql_query($strSQL); while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) { ここで配列に格納 } 配列への格納方法と、pointの降順にソートする 方法が知りたいです。 最終的に、Aさん、Dさん、Cさん、Bさんと なるようにしたいです。

    • ベストアンサー
    • PHP