ネストされたデータ構造を構築する際の困難


14

APIのJSONメッセージを作成しようとしているときに、簡単だと思った何かを実行するのに苦労しました。次のようなメッセージを作成する必要がありました。

{ "list": [ { "foo": 1, "bar": 2 } ] }

しかし、私の最初の試みはうまくいきませんでした:

say to-json { foo => [ { a => 1, b => 2 } ] };
# {"foo":[{"a":1},{"b":2}]}

物事を単純化しようとすると、さらに混乱しました:

say { foo => [ { a => 1 } ] };
# {foo => [a => 1]}
# Note that this is not JSON, but I expected to see curly braces

次に、いくつかの一時変数を使用しようとしましたが、うまくいきました:

my @list = { a => 1 };
say to-json { foo => @list };
# {"foo":[{"a":1}]}

my %hash = ( a => 1 );
say to-json { foo => [ %hash ] };
# {"foo":[{"a":1}]}

何が起きてる?

そして、追加の一時変数なしで希望の出力を達成できる方法はありますか?


1
say to-json { foo => [ { a => 1 } ] };{"foo":[{"a":1}]}ではなく、のように出力する必要があります{"foo":["a":1]}。後者はタイプミスですよね?そうでない場合、何をsay $*PERL.compiler.version;言いますか?
レイフ

うーん、そうだね。私が何かを試していたときに私は物事を誤解したと思います。でも、say to-json { foo => [ a => 1 ] }出力{"foo":[{"a":1}]}誰が私はそれを得たとき、私が今までやった場合、私は、入力した内容を知っているので。悪い!
jja

回答:


17

単一引数ルールを発見しました。Rakuの多数の構成要素は、それらが提供する引数を繰り返します。これには、[...]array composerが含まれます。これが、私たちが言うときの理由です。

say [1..10];

1ではなく10要素を含む配列を取得しますが、次のことも意味します。

say [[1,2]];

を反復する[1,2]ため[1,2]、内部配列が存在しないかのように-になります。A Hashはそのペアを反復処理するため、次のようになります。

{ foo => [ { a => 1, b => 2 } ] }

実際に生成します:

{ foo => [ a => 1, b => 2 ] }

つまり、配列にはペアがあります。次に、JSONシリアライザーは各ペアを1要素のオブジェクトとしてシリアル化します。

解決策は、単一要素のイテラブルを作成することです。中置,演算子はリストを生成するものなので、これを使用できます。

say to-json { foo => [ { a => 1, b => 2 }, ] };
#                        note the , here ^

次に、反復される単一の引数はハッシュを含む1要素のリストであり、必要な結果が得られます。

それを覚える簡単な方法:リスト、配列、またはハッシュの値を指定するときは、単一​​の要素リストを使用する場合でも、最後のコンマを常に使用してください。


2
もう1つの方法は、スカラーで項目化することです:{foo => [$ {a => 1、b => 2}]}
jakar
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.