新規記事投稿
フォロー記事投稿
記事のキャンセル
From: にあ
<nir@mxa.meshnet.or.jp>
Subject: Re: [Q] perl での 二つ以上のキーを用いたソート
Date: 1998/08/07 07:50:32
Reference: mesh.program/00528
8月6日に、素人でGO!さんは書きました。
>確かにそんなことが書いてありました。
>そこで素人の質問になるわけですが…配列の中に名前を付けるにはどうすればいいのでしょうか?
>
えーと、先の例はperl4でも使えるように、多次元配列は使わずに、個々の比較項目を
別個に連想記憶に入れてからソートするものでしたので、例えば、
#!/usr/local/bin/perl4
while (<DATA>) {
chop;
($date, $tasty, $cheap, $cute, $key) = split(/,\s*/);
push(@shop, $key);
$date{$key} = $date;
$tasty{$key} = $tasty;
$cheap{$key} = $cheap;
$cute{$key} = $cute;
}
@sorted = sort good @shop;
foreach $key (@sorted) {
printf("%s, (%s, %s, %s), %s\n",
$date{$key}, $tasty{$key}, $cheap{$key}, $cute{$key}, $key);
}
exit(0);
sub good {
$tasty{$a} cmp $tasty{$b}
||
$cheap{$a} cmp $cheap{$b}
||
$cute{$a} cmp $cute{$b}
||
$a cmp $b;
}
__END__
1998/04/23, D, B, E, 三茶のA
1998/05/10, B, C, A, 広尾のB
1998/05/11, C, A, B, 表参道のA
1998/06/26, B, A, C, 用賀のC
1998/07/05, D, B, A, 外苑前のA
とかなっていると、出力は、
1998/06/26, (B, A, C), 用賀のC
1998/05/10, (B, C, A), 広尾のB
1998/05/11, (C, A, B), 表参道のA
1998/07/05, (D, B, A), 外苑前のA
1998/04/23, (D, B, E), 三茶のA
とかになるわけです。
>@店 の中に 5つ(見つけた日付、おいしさ、安さ、かわいさ、場所)項目があったとします。
>そんな場合にこういうソートをするとき、どのように指定すればいいんでしょうか。
>
perl5での多次元配列(まがい)を使ってデータを入れてるとすると、配列の添字で指定した方が
やりやすいでしょうね。例えば、
#!/usr/local/bin/perl5
$tasty = 1;
$cheap = 2;
$cute = 3;
while (<DATA>) {
chop;
push(@shop, [split(/,\s*/)]);
}
@sorted = sort good @shop;
foreach $shop (@sorted) {
printf("%s, (%s, %s, %s), %s\n", @$shop);
}
exit(0);
sub good {
$$a[$tasty] cmp $$b[$tasty]
||
$$a[$cheap] cmp $$b[$cheap]
||
$$a[$cute] cmp $$b[$cute]
||
$a cmp $b;
}
__END__
1998/04/23, D, B, E, 三茶のA
1998/05/10, B, C, A, 広尾のB
1998/05/11, C, A, B, 表参道のA
1998/06/26, B, A, C, 用賀のC
1998/07/05, D, B, A, 外苑前のA
でも同じ出力になりますね。
多次元配列では無くて、ハッシュの配列を使えば、
#!/usr/local/bin/perl5
while (<DATA>) {
chop;
($date, $tasty, $cheap, $cute, $key) = split(/,\s*/);
$shop = {date => $date,
tasty => $tasty,
cheap => $cheap,
cute => $cute,
key => $key};
push(@shop, $shop);
}
@sorted = sort good @shop;
foreach $shop (@sorted) {
printf("%s, (%s, %s, %s), %s\n",
$shop->{date}, $shop->{tasty}, $shop->{cheap}, $shop->{cute}, $shop->{key});
}
exit(0);
sub good {
$a->{tasty} cmp $b->{tasty}
||
$a->{cheap} cmp $b->{cheap}
||
$a->{cute} cmp $b->{cute}
||
$a->{key} cmp $b->{key};
}
__END__
1998/04/23, D, B, E, 三茶のA
1998/05/10, B, C, A, 広尾のB
1998/05/11, C, A, B, 表参道のA
1998/06/26, B, A, C, 用賀のC
1998/07/05, D, B, A, 外苑前のA
な感じになりますか。もちろん出力は同じです。