4

()たとえば、Perl[]で使用する場合と、角括弧を使用する場合の配列のサイズをどのように見つけるかの違いは何ですか?

my @myarr = ( # Parenthesis
                [ "itemone", "itemoneb", "itemonec" ],
                [ "itemtwo", "itemtwob", "itemtwoc" ]
               );

my @myarr = [ # Square bracket
                [ "itemone", "itemoneb", "itemonec" ],
                [ "itemtwo", "itemtwob", "itemtwoc" ]
               ];

説明ありがとうございます。私はまだこれを理解しようとしていますが、現時点では少し混乱しています。ここでデータを反復処理する方法がまだわかりません。

#!/usr/bin/perl -w

use strict;
use FindBin qw($Bin);
use Cwd;
use Data::Dumper;

my @mynames = (
                [ "myname", "mydescription", "mydata"],
                [ "myname2", "mydescription2", "mydata2"],
                [ "myname3", "mydescription3", "mydata3"],
               );


go();

sub go {
    start(\@mynames);
}

sub start {
    my @input_name = shift;

    # This works
    #print @input_name->[0][0][0];
    #die;

    # This Shows
    #print Dumper(@input_name);
    #$VAR1 = [
    #          [
    #            'myname',
    #            'mydescription',
    #            'mydata'
    #          ],
    #          [
    #            'myname2',
    #            'mydescription2',
    #            'mydata2'
    #          ],
    #          [
    #            'myname3',
    #            'mydescription3',
    #            'mydata3'
    #          ]
    #        ];

    # How do I iterate?
    #for my $i (0..@$input_name) {
    #    my $name = "";
    #    my $description = "";
    #    my $data = "";
    #
    #}
}
4

4 に答える 4

6

これは間違っています:

my @myarr = [
                [ "itemone", "itemoneb", "itemonec" ],
                [ "itemtwo", "itemtwob", "itemtwoc" ]
               ];

次のいずれかである必要があります。

my $myarr = [
                [ "itemone", "itemoneb", "itemonec" ],
                [ "itemtwo", "itemtwob", "itemtwoc" ]
               ];

上記の「$myarr」です。角括弧は、スカラーであるリストへの参照を返します。したがって、「@」の代わりに「$」を使用する必要があります。

または

my @myarr = (
                [ "itemone", "itemoneb", "itemonec" ],
                [ "itemtwo", "itemtwob", "itemtwoc" ]
               );

上記の「[]」ではなく「()」です。「()」はリストを返すため、「@」が必要です。

AoA を反復処理する以下のコードを確認してください。このようにして、AoA のすべての要素にアクセスできます。個々の要素と同様に:

#!/usr/bin/perl -w
use strict;

my @mynames = (
                [ "myname", "mydescription", "mydata"],
                [ "myname2", "mydescription2", "mydata2"],
                [ "myname3", "mydescription3", "mydata3"],
              );

### To access all the elements in above AoA
foreach my $a (@mynames)
{
    foreach my $b ( @{$a} )
    {
        print $b."\t";
    }
    print "\n";
}
print "====================================\n";

### To access individual elements:
print $mynames[1][2]."\n"; ### It prints mydata2

perlrefを読んで、Perl リファレンスとネストされたデータ構造を学び、理解することをお勧めします。

于 2012-10-30T06:51:05.493 に答える
2

括弧は配列やリストを作成しません。コードの意味のある比較を示しましょう。

my @myarr1 = (
                [ "itemone", "itemoneb", "itemonec" ],
                [ "itemtwo", "itemtwob", "itemtwoc" ]
             );

my @myarr2 = (
                [
                   [ "itemone", "itemoneb", "itemonec" ],
                   [ "itemtwo", "itemtwob", "itemtwoc" ]
                ],
             );

@myarr12 つの要素を持つ AoA です。
@myarr2要素が 1 つの AoAoA です。

によって参照される配列のサイズを見つけるには$myarr2[0]、スカラー コンテキストで次を使用します。

@{ $myarr2[0] }

そうは言っても、おそらく使用するつもりでした

my $myarr2 = [
                [ "itemone", "itemoneb", "itemonec" ],
                [ "itemtwo", "itemtwob", "itemtwoc" ]
             ];

その場合、スカラー コンテキストで次を使用します。

@$myarr2     # Short for @{ $myarr2 }
于 2012-10-30T06:47:40.097 に答える
1

これは、多次元配列を反復処理する方法に関する更新された質問に対する回答です。

配列の配列

my @mynames = (
    [qw(myname  mydescription  mydata )], # the same as 'myname', 'my...', ...
    [qw(myname2 mydescription2 mydata2)],
    [qw(myname3 mydescription3 mydata3)],
);

(コメントで述べられているように、qw(foo bar)は単なる凝った書き方'foo', 'bar'です。) これは基本的に AoA (配列の配列) であり、次のように使用できます。

愚かな反復

foreach my $row (@mynames) {
    foreach my $col (@$row) {
        say $col;
    }
    say 'done with this row';
}

出力:

myname
mydescription
mydata
done with this row
myname2
mydescription2
mydata2
done with this row
myname3
mydescription3
mydata3
done with this row

しかし、この AoA についてもう少し知っています。

そのばかげた反復ではありません

foreach my $row (@mynames) {
    say join ', ' => @$row;
}

出力:

myname, mydescription, mydata
myname2, mydescription2, mydata2
myname3, mydescription3, mydata3

$rowは配列参照であり、そのリスト値を で使用するにはjoin、 で逆参照する必要があり@$rowます。しかし、もっとうまくやることができます:

ここで構造について詳しく知ることができます

foreach my $row (@mynames) {
    say "name: $row->[0], description: $row->[1], data: $row->[2]";
}

出力:

name: myname, description: mydescription, data: mydata
name: myname2, description: mydescription2, data: mydata2
name: myname3, description: mydescription3, data: mydata3

最初の項目は名前、2 番目は説明、3 番目は何らかのデータ値であることがわかっているため、出力でこの事実をユーザーに簡単に伝えることができます。$row->[42]は、単純な array で同じことを行うのと比較して、配列 ref 内の単一の値にアクセスする方法$array[42]です。

しかし、私たちはもっとうまくやることができます!

ハッシュのハッシュ

構造について多くのことを知っているので、ハッシュのハッシュ (HoH) を使用してこの構造を表現する方がはるかに優れています。最初の項目は残りの項目の (できれば一意の) 名前のようなものであるように見えるので、それをハッシュ キーに使用できますが、説明とデータは新しいハッシュ リファレンスに入ります。

my %data = (
    myname  => {description => 'foo', data => 42},
    myname2 => {description => 'bar', data => 17},
    myname3 => {description => 'baz', data => 37},
);

データの反復処理が大幅に改善され、コードがより読みやすく堅牢になりました。

foreach my $name (keys %data) {
    say "name       : $name";
    say "description: $data{$name}{description}";
    say "data       : $data{$name}{data}";
}

出力:

name       : myname
description: foo
data       : 42
name       : myname3
description: baz
data       : 37
name       : myname2
description: bar
data       : 17

ただし、ご覧のとおり、出力は順序付けされていません。これは問題ではないかもしれませんが、順序を定義したい場合は で行うことができますsort。この柔軟な構造を使用すると、たとえば特定のデータ値で並べ替えることができます。

データで並べる

foreach my $name (sort {$data{$a}{data} <=> $data{$b}{data}} keys %data) {
    say "name       : $name";
    say "description: $data{$name}{description}";
    say "data       : $data{$name}{data}";
}

出力:

name       : myname2
description: bar
data       : 17
name       : myname3
description: baz
data       : 37
name       : myname
description: foo
data       : 42

perldoc -f sortでこれがどのように機能するかについてもっと読んでください。

ハッシュの配列

名前が一意でない場合は、次のようなハッシュの配列を使用できます。

my @data = (
    {name => 'myname', description => 'mydescription', data => 'mydata'},
    # ...
);

この構造をどのように操作するかは、読者のための簡単な演習として残しておきます。それが役に立てば幸い!

もっと読む

perlreftut - 参照に関する MJD の非常に短いチュートリアル
perlref - Perl 参照とネストされたデータ構造
perldsc - perl データ構造クックブック

于 2012-10-30T11:05:23.323 に答える
0

角括弧[]はリストへの参照を作成しますが、括弧は単なるリストを作成します。

参照は、参照するリストを取得するために逆参照する必要があるという点で、ポインターのようなものです。参照はスカラー値です。つまり、スカラー変数に格納できます。プレフィックスを使用して@、リストを返すリスト参照を逆参照します。

\次のように、演算子を使用して参照を作成することもできます。

[ a,b,c ] is the same as \@a if @a = (a,b,c)

例:

my $a = [5,3,1];    # @$a is the same as (5,3,1)
push(@$a, 10);      # @$a is now (5,3,1,10)
join('-', @$a);     # "5-3-1-10"

say $a->[1];        # Prints "3" - an example of indexing
say $$a[1];         # Also prints "3"

sub foo { my $x = shift; say "Your list has ", scalar(@$x), " elements" }

foo($a);            # Prints: Your list has 4 elements

sub same_length { my ($x, $y) = @_; scalar(@$x) == scalar(@$y) }

same_length( $a, [6,7,8] );    # Returns false
same_length( $a, $a );         # Returns true

このsame_length例で、(参照を使用して) 2 つのリストをサブルーチンに渡したことに注意してください。これが、参照を使用する主な理由の 1 つです。

于 2012-10-30T06:46:21.550 に答える