代码之家  ›  专栏  ›  技术社区  ›  jja

在Raku中构建嵌套数据结构的困难表明需要进一步研究

  •  2
  • jja  · 技术社区  · 5 年前

    在尝试为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}]}
    

    这是怎么回事?

    有没有一种方法可以在没有额外临时变量的情况下实现我想要的输出?

    0 回复  |  直到 5 年前
        1
  •  17
  •   Jonathan Worthington    5 年前

    你已经发现了 single argument rule Raku中的许多构造都会迭代它们所提供的参数。这包括 [...] 阵列作曲家。这就是为什么当我们说:

    say [1..10];
    

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

    say [[1,2]];
    

    迭代 [1,2] ,从而导致 [1,2] -就好像内部阵列不存在一样。A. Hash

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

    实际生产:

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

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

    解决方案是生成一个可迭代的单个元素。中缀 , 操作符是生成列表的东西,所以我们可以使用它:

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

    然后,要迭代的单个参数是一个带哈希的1元素列表,你得到了想要的结果。

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