-2
@aoaoh;

$aoaoh[0][0]{21} = 31;
$aoaoh[0][0]{22} = 31;
$aoaoh[0][0]{23} = 17;

for $k (0 .. $#aoaoh) {
    for $i(0.. $#aoaoh) {
        for $val (keys %{$aoaoh[$i][$k]}) {
            print "$val=$aoaoh[$i][$k]{$val}\n";
        }
    }
}

出力は次のとおりです。

    22=31
    21=31
    23=17

しかし、私はそれを期待しています

    21=31
    22=31
    23=17

これのどこが間違っているのか教えてください。

また、出力を次のように取得するように値を並べ替えるにはどうすればよいですか

    23=17
    22=31
    21=31 (2 つのキーが同じ値の場合、値の大きいキーが先になります)
4

4 に答える 4

1

あなたが望むように聞こえます:

for $val (sort keys %{$aoaoh[$i][$k]}) {

と:

for $val (reverse sort keys %{$aoaoh[$i][$k]}) {

あなたのコメントから、あなたは純粋な逆ソートを望まないように見えますが。独自のソート関数を作成したい:

for $val (sort {$aoaoh[$i][$k]->{$a} <=> $aoaoh[$i][$k]->{$b} || $a <=> $b} keys %{$aoaoh[$i][$k]}) {
于 2010-03-24T18:19:32.690 に答える
0

このユーザーからの他の2つのまったく同じ質問に答えましたが、これが勝つように見えるので、ここでも答えます.

perlfaq4の回答から、どのようにして配列を並べ替えますか?


sort() に比較関数を提供します (perlfunc の sort で説明されています):

@list = sort { $a <=> $b } @list;

デフォルトの並べ替え関数は cmp、文字列比較で、(1, 2, 10) を (1, 10, 2) に並べ替えます。上記で使用されている <=> は、数値比較演算子です。

並べ替えたい部分を引き出すために複雑な関数が必要な場合は、並べ替え関数内で実行しないでください。並べ替え BLOCK は同じ要素に対して何度も呼び出される可能性があるため、最初に引き出します。各アイテムの最初の数字の後の最初の単語を取り出し、大文字と小文字を区別せずにそれらの単語を並べ替える方法の例を次に示します。

@idx = ();
for (@data) {
    ($item) = /\d+\s*(\S+)/;
    push @idx, uc($item);
    }
@sorted = @data[ sort { $idx[$a] cmp $idx[$b] } 0 .. $#idx ];

これは、シュワルツ変換として知られるようになったトリックを使用して、このように書くこともできます。

@sorted = map  { $_->[0] }
    sort { $a->[1] cmp $b->[1] }
    map  { [ $_, uc( (/\d+\s*(\S+)/)[0]) ] } @data;

複数のフィールドで並べ替える必要がある場合は、次のパラダイムが役立ちます。

@sorted = sort {
    field1($a) <=> field1($b) ||
    field2($a) cmp field2($b) ||
    field3($a) cmp field3($b)
    } @data;

これは、上記のキーの事前計算と組み合わせると便利です。

このアプローチの詳細については、 http: //www.cpan.org/misc/olddoc/FMTEYEWTK.tgz の「はるかに多くのことを知りたい」コレクションのソート記事を参照してください。

ハッシュのソートに関する perlfaq4 の後半の質問も参照してください。

于 2010-03-24T23:27:24.960 に答える
0

ハッシュが定義された順序でキーと値を返すことを期待しているように聞こえますが、perl ではそのような保証はありません。

順序付けの一部を処理するより複雑なデータ構造を実装するか、ディスプレイに並べ替えロジックを追加するか (単にループするのではなく)、Tie::Hashなどの順序付きハッシュをサポートするモジュールをロードすることができます。 ::索引付き

Tie::Hash::Indexed の実装は次のようになると思います。

my @aoaoh;

use Tie::Hash::Indexed;
tie my %hash, 'Tie::Hash::Indexed';
$aoaoh[0][0] = \%hash;

$aoaoh[0][0]{21} = 31;
$aoaoh[0][0]{22} = 31;
$aoaoh[0][0]{23} = 17;

for $k (0 .. $#aoaoh) {
    for $i(0.. $#aoaoh) {
        for $val (keys %{$aoaoh[$i][$k]}) {
            print "$val=$aoaoh[$i][$k]{$val}\n";
        }
    }
}
于 2010-03-24T19:02:03.797 に答える
0

Q1の答えは次のとおりです。

print "${$aoaoh[0][0]}{$_}=$_\n" for sort keys %{$aoaoh[0][0]};

次のように書くことができます:

for (sort keys %{$aoaoh[0][0]}) {
    print "${$aoaoh[0][0]}{$_}=$_\n"
}

そしてQ2の答え:

print "$_->[1]=$_->[0]\n" for
map { [$_->[0], $_->[1]] }
sort { $a->[0] cmp $b->[0] }
map { [ ${$aoaoh[0][0]}{$_}, $_ ] } keys %{$aoaoh[0][0]};
于 2011-05-29T20:33:14.840 に答える