构造嵌套数据结构时遇到困难


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

Answers:


17

您已经发现了单个参数规则。Raku中的许多构造都会迭代它们所提供的参数。这包括[...]阵列编辑器。这就是为什么当我们说:

say [1..10];

我们得到一个包含10个元素而不是1个元素的数组。但是,这也意味着:

say [[1,2]];

迭代[1,2],因此导致[1,2]-好像内部数组不存在。一个Hash迭代到其对,因此:

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

实际产生:

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

也就是说,数组具有对。然后,JSON序列化器将每对对象序列化为一个元素对象。

解决方案是产生一个单元素迭代。中缀,运算符是产生列表的原因,因此我们可以使用它:

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

然后,要迭代的单个参数是带有哈希值的1元素列表,您将获得所需的结果。

记住它的简单方法:指定列表,数组或哈希值时,即使使用单个元素列表,也要始终使用尾部逗号,除非您实际上是指定要从中填充的单个可迭代对象。


2
另一种方法是逐个标量:{foo => [$ {a => 1,b => 2}]}
jakar
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.