3

ここで私が間違っていることを誰かに教えてもらえますか? 考えられる配列/ハッシュタイプとソートクエリの可能な組み合わせをほぼすべて試しましたが、これを機能させることができないようです。

以下のハッシュ参照を次のようにソートしようとしていますvalue1:

my $test = {
    '1' => { 'value1' => '0.001000', 'value2' => 'red'},
    '2' => { 'value1' => '0.005000', 'value2' => 'blue'},
    '3' => { 'value1' => '0.002000', 'value2' => 'green'},
    '7' => { 'value1' => '0.002243', 'value2' => 'violet'},
    '9' => { 'value1' => '0.001005', 'value2' => 'yellow'},
    '20' => { 'value1' => '0.0010200', 'value2' => 'purple'}
};

この並べ替えループを使用する:

foreach (sort { $test{$a}->{'value1'} <=> $test{$b}->{'value1'} } keys \%{$test} ){
    print "key: $_ value: $test->{$_}->{'value1'}\n"
}

私は得る:

key: 1 value: 0.001000
key: 3 value: 0.002000
key: 7 value: 0.002243
key: 9 value: 0.001005
key: 2 value: 0.005000
key: 20 value: 0.0010200

整数で試してみましたが、同じことが起こるようです。

実際にハッシュをループする必要はありません。後で使用するために注文したいだけです。ハッシュの配列では簡単に実行できますが、ハッシュのハッシュではそうではありません..?

4

4 に答える 4

6

参照でキーを呼び出さないでください。実際のハッシュで呼び出します。

また、これは、ハッシュ参照であるため$test{$a}->、 である必要があります。$test->{$a}$test

foreach (sort { $test->{$a}{'value1'} <=> $test->{$b}{'value1'} } keys %{$test} ){
    print "key: $_ value: $test->{$_}->{'value1'}\n"
}

use strict;オンにしていた場合はuse warnings;、問題を警告する次のエラーが表示されます。

Global symbol "%test" requires explicit package name
于 2014-04-07T15:50:24.077 に答える
3

他の回答のソースと実際のコード例を提供したかっただけです。彼らが言ったようにkeys、引数のハッシュ参照を使用して呼び出しています。ドキュメントによると:


Perl 5.14 から、キーはスカラー EXPR を取ることができます。これには unblessed ハッシュまたは配列への参照が含まれている必要があります。引数は自動的に逆参照されます。キーのこの側面は非常に実験的であると考えられています。正確な動作は、Perl の将来のバージョンで変更される可能性があります。

for (keys $hashref) { ... }
for (keys $obj->get_arrayref) { ... }

ただし、これは私にとってはうまくいきます:

#!/usr/bin/perl
use strict;
use warnings;

my $test = {
    '1' => { 'value1' => '0.001000', 'value2' => 'red'},
    '2' => { 'value1' => '0.005000', 'value2' => 'blue'},
    '3' => { 'value1' => '0.002000', 'value2' => 'green'},
    '7' => { 'value1' => '0.002243', 'value2' => 'violet'},
    '9' => { 'value1' => '0.001005', 'value2' => 'yellow'},
    '20' => { 'value1' => '0.0010200', 'value2' => 'purple'}
};


foreach (sort { $test->{$a}->{'value1'} <=> $test->{$b}->{'value1'} } keys \%{$test} ) {
    print "key: $_ value: $test->{$_}->{'value1'}\n"
}

例:

matt@mattpc:~/Documents/test/10$ perl test.pl 
key: 1 value: 0.001000
key: 9 value: 0.001005
key: 20 value: 0.0010200
key: 3 value: 0.002000
key: 7 value: 0.002243
key: 2 value: 0.005000
matt@mattpc:~/Documents/test/10$ perl --version
This is perl 5, version 14, subversion 2 (v5.14.2) built for x86_64-linux-gnu-thread-multi
(with 88 registered patches, see perl -V for more detail)

keysこれは、私が推奨しない入力としてハッシュ参照を使用する場合です。

他の質問のアドバイスに従い、ハッシュへの参照を追加および変更するuse strictことをお勧めします。use warnings%{test}

于 2014-04-07T15:59:27.880 に答える
2

それは単にkeys %$testです。の引数はkeys、ハッシュ参照ではなく、ハッシュでなければなりません。\%${test}、参照と同じ$testです。

そして、ハッシュではなく、ハッシュ参照と同様に、を使用$test->{$a}します$test{$a}$test

foreach (sort { $test->{$a}->{'value1'} <=> $test->{$b}->'{value1'} } keys %$test) {
    print "key: $_ value: $test->{$_}->{'value1'}\n"
}

または構文糖衣を含む短い形式: 最初の矢印の後の追加の矢印は省略できます。また、ハッシュをアドレス指定するときに、文字列リテラル キーを引用符で囲む必要はありません。

foreach (sort { $test->{$a}{value1} <=> $test->{$b}{value1} } keys %$test) {
    print "key: $_ value: $test->{$_}{value1}\n"
}

use warnings;通常、少なくともデバッグの場合は、をオンにすると非常に役立ちます。

于 2014-04-07T15:52:31.157 に答える
0

\%{$test}私が見つけることができる唯一の間違いは、 hashを使用する必要があるところで hash refを使用することです%$testkeysそれで作業します。

于 2014-04-07T15:52:03.510 に答える