【问题标题】:How do I iterate through an array inside a Raku hash?如何遍历 Raku 哈希中的数组?
【发布时间】:2020-03-28 10:05:14
【问题描述】:

这似乎是一个简单的问题,但 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;

如何获得一个新的 @arr 变量来引用嵌套数组,而不会出现这种令人困惑的额外 [0] 索引层?这是一个错误,还是我对 Raku 的 Array/ref 处理的理解遗漏了什么?谢谢。

【问题讨论】:

    标签: arrays json hash raku


    【解决方案1】:

    当您将键arr 中的值分配给数组@arr 时,它会将%json{'arr'} 中的值(即数组对象["alpha","beta","delta","gamma"])放入@arr 中,这样您就得到了一个数组数组有 1 项。

    你有几个选择:

    您可以使用my @arr := %json{"arr"}@arr 绑定到%json{"arr"}

    或者您可以将%json{"arr"} 传递给带有my (@arr) = %json{"arr"} 的列表

    你必须记住在 Raku Array 中是 Objects。

    【讨论】:

    • 从性能的角度来看,my @arr := %json<arr> 解决方案是最好的,因为它不需要复制任何值,也不需要创建任何额外的对象。
    【解决方案2】:

    像往常一样,在写完+发布我的问题后,我回答了我自己的问题。

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

    我不太明白为什么这是必要的,但它提供了所需的行为。

    【讨论】:

    • %json{'arr'} 是一个标量(想想,对数组的引用)。调用 Array 方法是“取消引用”标量,或者更准确地说,是将标量内容从其标量容器放入列表容器中。你也可以写%json{'arr'}.flat|%json{'arr'},虽然我认为Array 方法在这种情况下要快一些。
    • 详细说明。在 Raku 中,数组和列表不会自动展平,因此 my @a = (1,2), (3,4) 将创建一个包含两个元素的列表数组,而不是一个包含四个整数的数组。
    • Raku 没有任何引用,它只有不可变的值和容器。您的解决方案执行以下操作: 1. 将散列中的 Array 对象强制为 Array:这本身就是一个 noop,但更重要的是,它丢失了在散列中存储 Array 的容器。由于Array 对象是可迭代的,它会将其值复制到@arr 数组中,可能会为大型数组做很多不必要的工作。
    猜你喜欢
    • 1970-01-01
    • 2016-09-03
    • 2012-08-22
    • 1970-01-01
    • 1970-01-01
    • 2014-12-30
    • 1970-01-01
    • 2014-06-21
    相关资源
    最近更新 更多