- 締切済み
値の比較がしたいのです
Perl超初心者です。 ある7つの変数$max[0]~$max[6]がありまして、それをすべて比較して同じ値がないか、あればどれとどれが同じなのか、を知りたいのですが今の自分の知識では一つひとつの組み合わせすべて書かなければなりません・・ 3つあったら、また追記しなければ、、などとしていたらすごい長文になってしまいました。 for文を使うのかもしれないと思いましたが、わかりやすいサイトに行きあたりません。何かヒントを頂けましたら幸いです。
- みんなの回答 (6)
- 専門家の回答
みんなの回答
- g_p_
- ベストアンサー率53% (28/52)
こんにちは、 #4氏の回答とほぼ同じなんですが、 単にインデックスが欲しいだけなら、 #! /usr/bin/perl use strict; use warnings; my @max = qw( 1 4 5 5 2 5 3); my @count_num = qw( 1 1 2 0 1 0 0); my($max_num) = sort { $max[$b] <=> $max[$a] or $count_num[$a] <=> $count_num[$b] or $a <=> $b }(0..$#max); print $max_num; みたいな感じでもいいかもです。
- pastelpurple
- ベストアンサー率70% (7/10)
既にスマートな回答が出されていますので、質問者さんの問題は 解決したことと思いますが、気になった点があるので少しだけ。 私への補足説明のところで > if($max[0] eq $max[1] && $count_num[0] eq $count_num[1] ){ と書かれていますが、まさか @max や @count_num って文字列ですか? や、サンプルが使用している配列が全て数値なんでだいじょぶかなーと思って。
- sakusaker7
- ベストアンサー率62% (800/1280)
できれば具体的なデータ(本物でなくてそれっぽいので良いです)と そのときの期待する結果なんてのを補足してもらえるとわかりやすいのですが、 こんな結果でいいのでしょうか? use strict; use warnings; use Data::Dumper; my @max = ( 10, 15, 50, 20, 25, 50, 30); my @count_num = (100, 100, 200, 100, 100, 200, 150); my @tmp; foreach my $idx (0 .. scalar @max -1) { push @tmp, [$idx, $max[$idx], $count_num[$idx]]; } #print Dumper(\@tmp); my @sorted = sort { $b->[1] <=> $a->[1] #@maxの値の大きい順に or $a->[2] <=> $b->[2] #同じなら @count_numの小さい順で or $a->[0] <=> $b->[0] #それも同じなら@maxでの順番の若い順に } @tmp; #並べ替える #print Dumper(\@sorted); print <<EOM; \@max の $sorted[0][0] 番目が $sorted[0][1] (\@count_num)と $sorted[0][2] (\@max)で 第一候補 EOM 実行結果: @max の 2 番目が 50 (@count_num)と 200 (@max)で 第一候補
- kabaokaba
- ベストアンサー率51% (724/1416)
要は値で分類できればいいのでは? 値1なのは添え字0と1 値2なのは添え字3 などのように. そうすれば,各値に何個の添え字があるかで 重複の存在も分かりますし, 同じ値の添え字も分かります. ハッシュ%classifiedは 「値」をキーとして,その値を持つ添え字から構成される 無名配列を値とします. この考え方のポイントは与えられた配列の各要素を使うのではなく 与えられた配列の「添え字」を中心にすることです. use strict; use warnings; use Data::Dumper; my %classified; my @list=(100,200,300,300,400,500,600,700,700); foreach (0..$#list){ $classified{$list[$_]}= [$_],next unless $classified{$list[$_]}; push @{$classified{$list[$_]}}, $_; } print Dumper \%classified;##ハッシュの中を覗く
- pastelpurple
- ベストアンサー率70% (7/10)
全て比較といっても、配列全てをそれぞれ比較するのですか? それとも、ある基準となる値を決めた上で、配列を走査するのですか? ま、上記二つも、走査の方法が大きく変わるわけではありませんが、 質問されるのでしたら、より具体的に説明される方が回答も得やすいと思いますよ。
補足
説明が足りず申し訳ありません。 すでにある計算をしている結果があり、それが$max[0]~$max[6]です。 この計算結果で$max[0]~$max[6]のうち、最も大きな値($max_num)が次のページ遷移のkeyとなるため、1回の処理で$max_numを一つに絞りたいというのが目的です。 そのため$max[0]~$max[6]の中で最も大きな値が複数ないか、ということをまずは確認したく、それからもし最も大きな値が複数あったらまた別の計算をしている変数$count_num[0]~$count_num[6]で数字が小さい方を優先的に、もし$count_numまで同じだったら[*]の数値が小さい順に・・・ということがしたいのです。ちなみに$max[*]の*と$count_num[*]の*の数はそれぞれに対応しています。 たとえば$max[0]と$max[6]が最も大きくて同じ値であるとき、$count_num[0]>$count_num[6]であれば、最終的に知りたい値$max_numは6であり、$count_num[0]=$count_num[6]であれば$max_numは0と導きだしたいです。 if($max[0] eq $max[1] && $count_num[0] eq $count_num[1] ){ $max_num=0; } などと書きだしていったら途方に暮れてしまいました。 少しでも簡略化できるとうれしく思います。
- sakusaker7
- ベストアンサー率62% (800/1280)
重複するデータが複数あったときとかはどうしますか? あと、重複している値がわかればよいですか?#!/usr/bin/perl # -*- coding: utf8 -* use strict; use warnings; sub get_dup { my %seen; $seen{$_}++ foreach (@_); my @r = grep {$seen{$_} > 1} keys %seen; } my @list = (1, 2, 2, 3, 4, 4, 6); my @dup = get_dup(@list); print join(':', @dup), "\n"; @list = (1, 2, 3, 3, 5, 6, 7); @dup = get_dup(@list); print join(':', @dup), "\n"; @list = (1, 2, 3, 4, 5, 6, 7); @dup = get_dup(@list); print join(':', @dup), "\n"; 実行結果: 4:2 3
補足
説明不足にてお手数をおかけし申し訳ありません。 #2の方の補足欄に実行したいことを記述させて頂きました。 重複するデータが複数ある場合、さらに条件があるので、素人の力技ではどうにもならず、ご相談させていただいた次第です。
お礼
御礼遅くなり申し訳ありません。 ハッシュ、を理解するのに相当時間を要してしまいました。。 まだまだです。。 理解しきっていないのですが、見よう見まねでなんとかできているようなものができまして、テスト中です。 本当にありがとうございました。