PHP初心者です。

csvデータから読み込んだデータをもとに、連想配列をソートしたいと考えています。
一行にたとえば
みかん,580,りんご,240,ぶどう,360,くり,110
といったかたちで、データが入っていて、複数行あります。
まず、各行内を
みかん=>580 といったかたちで、果物名をkey、値段をvalueにしていき、
さらに、それらをvalueの値順(値段が高い順)にソートして表示していきたいのですが、変数?を連想配列にする方法がわからず困っています。
また、各行の長さ(種類数)は一定ではなく、この処理を全行にわたって繰り返し行いたいと思っています。

漠然としていて申し訳ないのですが、、ざっくりとした流れと、連想配列部分の具体例について教えていただけないでしょうか。。。
よろしくおねがいいたします。

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:2007/08/05 08:40:59
  • 終了:2007/08/12 08:45:03

回答(5件)

id:KUROX No.1

KUROX回答回数3542ベストアンサー獲得回数1402007/08/05 09:03:15

ポイント35pt

これがもしかしてつかえるかも

http://www.res-system.com/item/508

自前でやりたいのなら、このあたりを参考にして

もう少し考えてみては

http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/php_k08.htm

id:GEN111 No.2

GEN111回答回数472ベストアンサー獲得回数582007/08/05 09:52:31

ポイント35pt

やり方はいろいろあると思いますが、例として


オーソドックスな感じ

<?php
$datafile = './data.csv' ; // CSV ファイル

$fh = fopen($datafile, 'r') ;
if ($fh) {
  flock($fh, LOCK_SH) ;

  $lst = array() ;
  while ($line = fgets($fh)) { // ファイルから一行ずつ読み込む
    $all = explode(',', chop($line)) ; // カンマで分割して配列に

    while (($key = array_shift($all)) && ($val = array_shift($all))) { // 配列の先頭から名前と値を取り出す
      $lst{$key} = $val ; // 連想配列にセット
    }
  }

  // ソートして表示
  asort($lst) ;
  echo '<pre>' ;
  print_r($lst) ;
  echo '</pre>' ;

  flock($fh, LOCK_UN) ;
  fclose($fh) ;
}
?>

正規表現を使って

while ($line = fgets($fh)) { // ファイルから一行ずつ読み込む
  preg_replace('/([^,]+),([^,]+)/e', '$lst[$1] = $2;', $line) ;
}

key,val,key,val ... のペアになってない場合は考慮していません。

PHP: 配列 - Manual

id:tezcello No.3

tezcello回答回数460ベストアンサー獲得回数692007/08/07 09:17:11

ポイント10pt

ある変数に収められている値(群)を連想配列にする方法 という事なので、こんなのはどうでしょう?


名前と値段のペアが何組あるか分らないので、preg_match_all でペア毎に取り出します。

後は、取り出したペア全てで連想配列に入れてやるだけです。

$source = file('ファイル名');
foreach($source as $str){{
  preg_match_all('/([^,]+),(\d+)/', $str, $res, PREG_SET_ORDER);
  foreach($res as $r) $lst[$r[1]] = $r[2];
}
arsort($lst);

(参考)http://www.php.net/manual/ja/function.preg-match-all.php

日本語のコードはEUCかUTF-8でないと果物名を直接キーには出来ませんので、ご注意を。

また、果物名に重複がある場合を考慮していません。


preg_match_all() の部分を明確にするために、ファイルの内容を配列に取り込んでいるでわざわざ2回 foreach を使っていますが、

file_get_contents() 等で一つの変数に入れてしまう事で1回でもできます。

その際は改行文字を無視するようなパターンを変更すればOKです。(CSVファイルにあわせて下さい)

$str = file_get_contents('ファイル名');
preg_match_all('/([^,\n]+),(\d+)/', $str, $res, PREG_SET_ORDER);
foreach($res as $r) $lst[$r[1]] = $r[2];

arsort($lst);
id:tobeoscontinue No.4

tobeoscontinue回答回数213ベストアンサー獲得回数532007/08/05 22:11:02

ポイント10pt

すべきことは

1.csvデータから読み込む

2.連想配列に変換する

3.ソートする。

の三つです。

<?php
$hash = array();
function chunk_combine($value, $key) {
	global $hash;
	$hash[$value[1]] = $value[0];
}

$files = file("data.csv");
$datas = implode (',', $files);
$datas = str_replace("\n", '', $datas);

$data_a = explode(',', $datas);
$chunk = array_chunk($data_a, 2);
array_walk($chunk, 'chunk_combine');
asort($hash);
print_r($hash);
?>

1.の読み込みはfile()が面倒がなく、簡単です。がこの場合、行単位の配列になります。

そこでimplode()を使って全てを連結して長い文字列にしてしまいます。このままでは行のlfが残っているのでstr_replace()で取り除きます。

2.がちょっと面倒で、定石があるのかもしれませんが解からないのでarray_walk()を使ってみました。foreachの方がわかりやすいんだけど。

まず長い文字列($datas)をexplode()を使って,で区切って配列にします。次にarray_chunk()で2個づつのペアの配列にします。array_walk()はforeachと同じような目的で使ってますが2個づつのペアが取り出されてchunk_combine()が実行されるので、その中のグローバルな$hashに追加しています。chunk_combine()の中で更新結果を返すいい方法がわからなかったのでグローバルを使ってます。

3.のソートは幾つかあるので目的に合わせて替えればいいでしょう。

少し助長なのですこしまとめると下記になります。

<?php
$hash = array();
function chunk_combine($value, $key) {
	global $hash;
	$hash[$value[1]] = $value[0];
}

$datas = str_replace("\n", '', implode (',', file("data.csv")));

array_walk(array_chunk(explode(',', $datas), 2), 'chunk_combine');
asort($hash);
print_r($hash);
?>

http://jp.php.net/manual/ja/ref.array.php

質問者が未読の回答一覧

 回答者回答受取ベストアンサー回答時間
1 tezcello 460 419 69 2007-08-07 09:12:29

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません