local($data) = @_;
$data =~ s/\n$//;
($name,$lv,$hp,$gp) = split(/,/,$data);
}
で、データを読み込んで、
<tr><td>$name</td><td>$lv</td><td>$hp</td><td>$gp</td></tr>\n";

という形で行ごとに出力しているんですが、これをきちんと並び替えて$lvの順に並ぶランキングリストを作りたいんです。

色々試してみたんですが、記録された順番のまま出力されてきたり、全然表示されなかったりでうまくいきません。

できるだけ初心者でも分かりやすい方法を教えてください。
よろしくお願いします。

A 回答 (1件)

 こういうのはどうでしょう?


 @data には、

  $data[0] = "www,2,www,www";
  $data[1] = "www,1,www,www";
  $data[2] = "www,4,www,www";
  $data[3] = "www,3,www,www";

 というデータが入っているものとし、

foreach ( @data ) {
  ($name,$lv,$hp,$gp) = split(/,/,$_);
  $_ = "$lv,$name,$hp,$gp";
}
@data = sort { $a <=> $b } @data;
foreach ( @data ) {
  ($lv,$name,$hp,$gp) = split(/,/,$_);
  $_ = "$name,$lv,$hp,$gp";
}

 あまりスマートなロジックじゃないですけど、これで $lv 順になります。
 昇順と降順を入れ替えるときは sort 関数の $a と $b を逆にします。
(見栄えのためにタブ文字を全角スペースにしてますので、コピーペーストするときはご注意を)
    • good
    • 0
この回答へのお礼

早速の御指導ありがとうございます。
教えて頂いたスクリプトを利用して、

  $data[0] = "www,2,www,www";
  $data[1] = "www,1,www,www";
  $data[2] = "www,4,www,www";
  $data[3] = "www,3,www,www";

の内容表示を、

local($data) = @_;
$data =~ s/\n$//;
foreach ( @data ) {
  ($name,$lv,$hp,$gp) = split(/,/,$_);
  $_ = "$lv,$name,$hp,$gp";
}
@data = sort { $a <=> $b } @data;
foreach ( @data ) {
  ($lv,$name,$hp,$gp) = split(/,/,$_);
  $_ = "$name,$lv,$hp,$gp";
}

としたんですが、何故か『$data[2]にはいってるデータ内容』だけが、$data[0]~$data[3] の分だけ出力されてしまいました・・・。
うまく説明できないんですが、
  $data[2] = "www,4,www,www";
  $data[3] = "www,3,www,www";
  $data[0] = "www,2,www,www";
  $data[1] = "www,1,www,www";
の順に出すはずが、出力されたのが
$data[2] = "www,4,www,www"
$data[2] = "www,4,www,www"
$data[2] = "www,4,www,www"
$data[2] = "www,4,www,www"
になってしまったんです。
どこを修正したらよいのか教えて頂けないでしょうか?
よろしくお願いします。

お礼日時:2002/03/23 21:22

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Qperlスクリプト s/^\s+//;  s/\s+$//;  return wantarray ? @out : $out[0]; について

自作の掲示板を作ろうと思い、perlの勉強をしている者です。人様の作ったスクリプトを解析しています。以下のスクリプトはライブラリに記述されていたものです。


sub tttt {
my @out = @_;
for (@out) {
s/^\s+//;
s/\s+$//;
}
return wantarray ? @out : $out[0];


このスクリプトなんですが、 s/^\s+//; の部分の「+」と s/\s+$//; の部分の「+$」、 また「return wantarray~」 の三つの部分のスクリプトが、どういった働きをしているの分かりません。専門書やウェブ上のリファレンスも色々調べたのですが・・。

分かる方いらっしゃいましたらご教授下さると幸いです。よろしくお願いします。

Aベストアンサー

まず前2つの「+」は,正規表現における,「直前の表現を一回以上繰り返し」をあらわします.
「\s」は空白文字一文字を表す正規表現ですので,「\s+」は,「一文字以上の空白文字」になります.
次に,最初の「^」と2番目の「$」は,その正規表現がどこに現れるかを示す記号です.それぞれ,先頭と最後尾にあることを示します.
したがって,「^\s+」は,「最初に空白が一文字以上ある文字列」に,
「\s+$」は「行末に空白が一文字以上ある文字列」にヒットします.
置換構文sはご存知なんですかね.すなわち,この2文で,行の最初と最後の空白を消しているんです.

次に, wantarray ですが,
http://www2u.biglobe.ne.jp/~MAS/perl/ref/wantarray.html
によると,このサブルーチンttttを呼び出すときに,何を返り値にしているかで真偽が決まる関数です.
呼び出す時に配列を希望していたら @out 全体を,変数を希望していたら $out[0]だけを返します.

Q$wfurikae = 1 if ( &ccom::getShukujitsu( &com::tD( $wwy,$wwm,$wwd )) ne '' );がよく

$wfurikae = 1 if ( &ccom::getShukujitsu( &com::tD( $wwy,$wwm,$wwd )) ne '' );

というスクリプトがあったのですが、

$wfurikae = 1 の後に;もいれずifがきています。

違和感があります。

どのような意味になるのでしょうか。

宜しくお願い致します。

Aベストアンサー

そのまんまだと思いますよ。
if 以下の条件が真の時 $wfurikae = 1となります。
Perlはいろいろな書き方ができますので、こういう書き方もありです。
英語の文法の並びにする書き方です。

Q$hts =~ s/##([^#]+)##/$FORM{$1}/g の意味を教えてください!

お世話になります。
perl素人なのですが必要に迫られてWEBで調べながら
ソースを解析していますが、次のコードで完全に止まってしまいました。

$hts =~ s/##([^#]+)##/$FORM{$1}/g

この場合、
#hts から ##([^#]+)## を探して $FORM{$1} に全て置き換えようとしていると思うのですが、以下2点が理解できず困っています。

1.##([^#]+)## の意味
$htsに##で囲まれた文字列が複数あるのでそれら全てを探すということでしょうか?

2.$FORM{$1} の意味
$1は1.で検索した結果だと思いますが、$FORM{ }は一体なんでしょうか?

素人がいきなり解析するのは無謀なのは承知の上ですが、
どうしても業務で必要なので、お知恵をお貸し下さい。
よろしくお願いいたします。

Aベストアンサー

1.
perlを基準に「正規表現」で調べてごらん

2.
同じくperlでHTMLのformデータを受け取る方法を調べてごらん

Qperlスクリプト

<html>~</html>の中に複数のperlスクリプトは書けるのでしょうか?
htmlファイル1つの中には、<html>~</html>は1つだと思うのですが、
phpだと<?php>~<?>とすれば、<html>~</html>の中に複数書けるみたいですが、perlでも書けるのでしょうか?

Aベストアンサー

通常書けません(書くのは別にかまいませんが期待通りにはならないでしょう)。
逆にPerlスクリプト中にHTMLをヒアドキュメントという形で記述することは一般的です。
PerlはWebが生まれる前からありましたが、PHPはWebの為に生まれました。

Q@b = grep(/マッチパターン/, @a);でなく@a = grep(/マッチパターン/, @a);でOKについて

@b = grep(/マッチパターン/,@a);だと配列@aの中でマッチするものを探して@bに入れる・・・というのは理解できるんですが、
@a = grep(/マッチパターン/,@a);とし、
foreach $_ (@a) {
print $_;
}
で参照した場合、@aの中のマッチパターンにマッチするのだけ表示されますけれども、ここでマッチしないのは削除されるのでしょうか・・。

@aから@aにいれる・・・となる事について、どのように@aにマッチしたものを入れ、マッチしないものは削除されるのかの仕組みについて、ご説明できる方はいらっしゃいますでしょうか(例えば内部的にpopやshiftが機能していて・・・みたいな事なのかな・・とか思うんですけれども)

お手数ですが、ご存知の先生方ご教授願えましたら幸いです。

Aベストアンサー

#1でのTacosanさんの回答の1です。
つまり、
@a = grep(/マッチパターン/,@a);
これは
@aの内容を列挙→ grepに掛ける→条件に合うものだけのリストを作成→作成したリストを代入。
となります。
grepに掛かる前の@aの内容は、代入の際に「丸ごと」破棄されます。

perly.y
/* Binary operators between terms */
termbinop:term ASSIGNOP term /* $x = $y */
{ $$ = newASSIGNOP(OPf_STACKED, $1, IVAL($2), $3);
TOKEN_GETMAD($2,$$,'o');
}

op.c

OP *
Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
{
dVAR;
OP *o;

(略

if (is_list_assignment(left)) {
static const char no_list_state[] = "Initialization of state variables"


という具合なので、代入の左右両辺が同じ変数かどうかのチェックは多分やってません。

#1でのTacosanさんの回答の1です。
つまり、
@a = grep(/マッチパターン/,@a);
これは
@aの内容を列挙→ grepに掛ける→条件に合うものだけのリストを作成→作成したリストを代入。
となります。
grepに掛かる前の@aの内容は、代入の際に「丸ごと」破棄されます。

perly.y
/* Binary operators between terms */
termbinop:term ASSIGNOP term /* $x = $y */
{ $$ = newASSIGNOP(OPf_STACKED, $1, IVAL($2), $3);
TOKEN_GETMAD($2,$$,'o');
}

op.c

OP *
Perl_newASSIGNOP...続きを読む


おすすめ情報