Rakuハッシュ内の配列を反復するにはどうすればよいですか?


8

これは簡単な質問のようですが、Perl6 / Rakuは期待どおりに動作していません。ハッシュ内の配列への参照を作成しようとしていますが、期待どおりの動作が得られません。Perl5では、答えは参照によって配列にアクセスすることを含みますが、Perl6 / Rakuに対応する構文は見当たりません。

my $jsonstr = q:to/END/;
{
    "arr" : [
        "alpha","beta","delta","gamma"
    ]
}
END

my %json = from-json $jsonstr;
my @arr = %json{'arr'};
say "Arr length is " ~ @arr.elems; # Expect 4, get 1
say "Orig length is " ~ %json{'arr'}.elems; # Get expected value of 4
say "Arr[0] is " ~@arr[0].^name ~ " of length " ~ @arr[0].elems; # First index is array

say %json{'arr'}[0]; # Indexing into array in original location works as expected
say @arr[0][0]; # But when assigned, it needs an extra index

my @arr2 = @arr[0]; # Same issue in re-assignment here
say "Arr2[0]: " ~ @arr2[0] ~ ", length of " ~ @arr2.elems;

この混乱する余分な[0]インデックスレイヤーなしで、ネストされた配列を参照する新しい@arr変数を取得するにはどうすればよいですか?これはバグですか、それともRakuのArray / ref処理の理解で何か不足していますか?ありがとう。

回答:


7

キーの値をarr配列@arrに割り当てる%json{'arr'}と、配列オブジェクトである値を取得["alpha","beta","delta","gamma"]して@arr配置するため、1つの項目を持つ配列の配列を取得します。

いくつかのオプションがあります:

あなたはバインドすることができます@arr%json{"arr"}してmy @arr := %json{"arr"}

または%json{"arr"}、リストにを渡すことができますmy (@arr) = %json{"arr"}

Raku ArrayはObjectであることに注意してください。


5
パフォーマンスの観点からは、my @arr := %json<arr>値をコピーしたり、追加のオブジェクトを作成したりする必要がないため、ソリューションが最適です。
Elizabeth Mattijsen

2

いつものように、質問を書いて投稿した後、自分の質問に答えました。

my @arr = %json{'arr'}.Array;

これが必要な理由はよくわかりませんが、望ましい動作が得られます。


3
%json{'arr'}スカラーです(配列への参照と考えてください)。Arrayメソッドを呼び出すと、スカラーが「逆参照」されます。つまり、スカラーコンテナーからリストコンテナーにスカラーコンテンツが配置されます。%json{'arr'}.flatまたはを書いてもかまいませんが、この場合の方が少し高速|%json{'arr'}だと思いますArray
Holli

1
詳しく説明します。Rakuでは、配列とリストは自動的にフラット化されないためmy @a = (1,2), (3,4)、4つの整数の配列ではなく、2つの要素を持つリストの配列が作成されます。
Holli

2
Rakuには参照がなく、不変の値とコンテナーしかありません。ソリューションは次のことを行います。1. Arrayハッシュ内のオブジェクトを強制的にanに強制しますArray。これ自体は何も起こらないものですが、より重要なのは、配列がハッシュに格納されていたコンテナーを失うことです。ArrayオブジェクトはIterableであるため、その値を@arr配列にコピーし、大きな配列に対して多くの不要な作業を行う可能性があります。
Elizabeth Mattijsen
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.