スレッド表示 | フラット表示〕 全トピック 920 件中 382 番目 次≫ ≪前

配列のソートがうまくいきません

created: 2005-08-25 11:50 | modified: 2005-08-28 03:37 | reply: 5

[2492] 配列のソートがうまくいきません

user: ゴロー | created: 2005-08-25 11:50
DBの使用できない環境ですので、アップしてある
下記のようなCSVファイルを読み込み、
任意の教科にソートをかけて表示させたいと思っています。

----------------seiseki.csv-----------
登録番号,名前,国,数,英,・・・・・
1,一郎,10,70,40,・・・・・
2,二郎,80,15,20,・・・・・
3,三郎,50,40,60,・・・・・
--------------------------------------
           ↓
(処理例)
----------------英語成績--------------
登録番号|名前|国|数|英|・・・・・
3|三郎|50|40|60|・・・・・
1|一郎|10|70|40|・・・・・・
2|二郎|80|15|20|・・・・・
--------------------------------------

横一列の配列内のソートなら簡単に処理できるのですが
縦の数値にソートをかけ表示させることができません。
どのような処理をすればこれが可能になるのでしょうか?
reply: 2493 2494 2497 2511 返信 編集 削除

[2493] Re:配列のソートがうまくいきません

user: ぱぴよん | created: 2005-08-25 12:19
ゴローさんはじめまして、ぱぴよんと申します。

データを配列に代入してソートする方法はいかがでしょうか?
配列ならソート関数がいくつかあります。
【参考:http://jp.php.net/manual/ja/ref.array.php


> ----------------seiseki.csv-----------
> 登録番号,名前,国,数,英,・・・・・
> 1,一郎,10,70,40,・・・・・
> 2,二郎,80,15,20,・・・・・
> 3,三郎,50,40,60,・・・・・
> --------------------------------------
>            ↓
> (処理例)
> ----------------英語成績--------------
> 登録番号|名前|国|数|英|・・・・・
> 3|三郎|50|40|60|・・・・・
> 1|一郎|10|70|40|・・・・・・
> 2|二郎|80|15|20|・・・・・
> --------------------------------------

例でいくと以下のようなイメージです。
$array = array();
$array["40一郎"] = "1,一郎,10,70,40,・・・・・";
$array["20二郎"] = "2,二郎,80,15,20,・・・・・";
$array["60三郎"] = "3,三郎,50,40,60,・・・・・";

$array を Key でソートする。
Parent: 2492  返信 編集 削除

[2494] 二次元配列のソート

user: ゆうじ | created: 2005-08-25 13:08
こんにちは。

usort関数と独自の比較関数を使って実現できます。
http://jp.php.net/manual/ja/function.usort.php

<?php
// CSVから読み込んだ二次元配列のイメージ
$records = array(
array('1', '一郎', '10', '70', '40'),
array('2', 'ニ郎', '80', '15', '20'),
array('3', '三郎', '50', '40', '60')
);

// 国語(key:2)用ソート関数
function jp_cmp ( $rec1, $rec2 )
{
if ($rec1[2] == $rec2[2]) {
return 0;
} elseif ($rec1[2] > $rec2[2]) {
return -1;
} else {
return 1;
}
}

// 数学(key:3)用ソート関数
function math_cmp ( $rec1, $rec2 )
{
if ($rec1[3] == $rec2[3]) {
return 0;
} elseif ($rec1[3] > $rec2[3]) {
return -1;
} else {
return 1;
}
}

// 元データ
echo '<div>元データ</div><pre>';
var_dump($records);
echo '</pre>';

// 国語でソート
usort($records, 'jp_cmp');
echo '<div>国語成績順</div><pre>';
var_dump($records);
echo '</pre>';

// 数学でソート
usort($records, 'math_cmp');
echo '<div>数学成績順</div><pre>';
var_dump($records);
echo '</pre>';
?>

比較関数は科目ごとに必要になります。
Parent: 2492  reply: 2495 返信 編集 削除

[2495] クラスを使った場合

user: ゆうじ | created: 2005-08-25 15:03
科目が多いといちいち比較関数を書くのが
面倒だと感じたのでクラス化してみました。

<?php
// CSVから読み込んだ二次元配列のイメージ
$records = array(
array('1', '一郎', '10', '70', '40'),
array('2', 'ニ郎', '80', '15', '20'),
array('3', '三郎', '50', '40', '60')
);

// 二次元配列を任意のキーで並べ替えるオブジェクト
class TwoSort
{
var $table;
var $key;

/******
* Private
*/

/* 降順並べ替え用比較関数 */
function down_cmp ( $rec1, $rec2 )
{
if ($rec1[$this->key] == $rec2[$this->key]) {
return 0;
} elseif ($rec1[$this->key] > $rec2[$this->key]) {
return -1;
} else {
return 1;
}
}

/* 昇順並べ替え用比較関数 */
function up_cmp ( $rec1, $rec2 )
{
if ($rec1[$this->key] == $rec2[$this->key]) {
return 0;
} elseif ($rec1[$this->key] < $rec2[$this->key]) {
return -1;
} else {
return 1;
}
}

/******
* コンストラクタ
* 引数:$array :並べ替え対象の二次元配列
*/
function TwoSort ( &$array )
{
$this->table =& $array;
}

/******
* 任意のキーで並べ替え実行
* 引数:$key :並べ替え対象のキー又は添え字
* $option :true(降順), false(昇り順)
*/
function keysort ($key, $option = false)
{
$this->key = $key;
if ($option) {
usort($this->table, array(&$this, 'down_cmp'));
} else {
usort($this->table, array(&$this, 'up_cmp'));
}
}
}


// 元データ
echo '<div>元データ</div><pre>';
var_dump($records);
echo '</pre>';

$TwoSort = new TwoSort($records);

// 国語でソート
$TwoSort->keysort(2, true);
echo '<div>国語成績順</div><pre>';
var_dump($records);
echo '</pre>';

// 数学でソート
$TwoSort->keysort(3, true);
echo '<div>数学成績順</div><pre>';
var_dump($records);
echo '</pre>';
?>
Parent: 2494  返信 編集 削除

[2497] ありがとうございます。

user: ゴロー | created: 2005-08-25 23:11
ぱぴよん様、ゆうじ様、大変お役に立つレスありがとうございます。
keyでのソート。二次元配列でのソート。配列って難しいですね。
難しいのは配列だけじゃないですが…(汗)
お教えいただいたソースを移行して動作させることは、
私のスキル不足が原因でまだできませんので、
成功のご報告までもうしばらくお時間をください。
Parent: 2492  返信 編集 削除

[2511] 途中経過です。

user: ゴロー | created: 2005-08-28 03:37
ゆうじさんが最初に教えてくださったソースを使ってみました。
試行錯誤を繰り返すうちに何とか動かせるようになったのですが、
ソートの条件が複数になってしまったので、あちこち探したり、
本を見ながら自分なりにアレンジしてみました。
function cmp($rec1,$rec2) {
$result = -($rec1[9] - $rec2[9]);//降順のため先頭に(-)
if($result==0) {
$result= -($rec1[6]-$rec2[6]);//降順のため先頭に(-)
}
return $result;
}
最初にソースを教えていただかなければ、まったく理解ができませんでした。
ここで教えていただいたおかげです。本当にありがとうございます。
理解と言っても、自分には壁が高いので本当に少しだけ触れるレベルで、
2つ目のクラスやオブジェクトに至っては、壁でなくエベレストです…(汗)
Parent: 2492  返信 編集 削除
スレッド表示 | フラット表示〕 全トピック 920 件中 382 番目 次≫ ≪前
ページの一番上へ
Googleグックマークに登録 Yahooグックマークに登録 livedoorクリップに登録 @niftyクリップに登録 はてなブックマークに登録 deliciousに登録 Buzzurlに登録 FC2ブックマークに登録
最近更新された掲示板トピックス
管理人Blog
Yahoo Search

最近更新したNote
PHPマニュアル
今日のブックマーク
PHPマニュアル関数検索
関数名を入力し検索ボタンをクリック↑