【问题标题】:Unexpected Hash flattening意外的哈希扁平化
【发布时间】:2018-05-20 21:59:35
【问题描述】:

我正在寻找解释为什么这两个数据结构不相等:

$ perl6 -e 'use Test; is-deeply [ { a => "b" } ], [ { a => "b" }, ];'
not ok 1 -
# Failed test at -e line 1
# expected: $[{:a("b")},]
#      got: $[:a("b")]

Hashes 和 Arrays 中的尾随逗号没有意义,就像在 P5 中一样:

$ perl6 -e '[ 1 ].elems.say; [ 1, ].elems.say'
1
1

但如果没有它,Hash 会以某种方式丢失,并且会被展平为 Pairs 数组:

$ perl6 -e '[ { a => "b", c => "d" } ].elems.say;'
2

我怀疑这里适用一些伟大的列表重构法则,但我想获得更详细的解释以了解这种扁平化背后的逻辑。

【问题讨论】:

    标签: hashmap raku


    【解决方案1】:

    Hashes 和 Arrays 中的尾随逗号没有意义,就像在 P5 中一样

    不,不是没有意义:

    (1 ).WHAT.say ; # (Int)
    (1,).WHAT.say ; # (List)
    

    Great List Refactor 中最大的简化是切换到 the single argument rule 以迭代功能1。也就是说,像for 或数组和哈希组合器(和下标)这样的特性总是得到一个参数。这确实是您原始示例的情况。

    单个参数可能 - 通常是 - 一个值列表,甚至可能是一个列表列表等,但顶级列表仍然是迭代功能的单个参数。

    如果迭代功能的单个参数具有Iterable 角色(例如列表、数组和散列),则它会被迭代。 (这是一个不精确的表述;更精确的表述请参见my answer“何时调用迭代器方法?”。)

    所以这里要注意的关于额外逗号的关键是,如果单个参数扮演Iterable角色,例如1,那么最终结果是完全相同的就好像参数是一个只包含那个值的列表(即1,):

    .perl.say for {:a("b")}   ; # :a("b")     Iterable Hash was iterated
    .perl.say for {:a("b")} , ; # {:a("b")}   Iterable List was iterated
    .perl.say for 1           ; # 1           Non Iterable 1 left as is
    .perl.say for 1 ,         ; # 1           Iterable List was iterated
    

    “在声明单个元素列表时使用尾随逗号保留结构 [以外] 的典型方法”(请参阅​​下面的注释),即 stop 一个 Iterable 值像往常一样被迭代,是通过 item 使用 $ 对其进行化:

    my @t = [ $[ $[ "a" ] ] ];
    @t.push: "b";
    @t.perl.say; # [[["a"],], "b"]
    

    1for的情况下,迭代用于获取要传递给某些代码的值;在作曲家的情况下,让值成为正在构造的数组/散列的元素;在下标的情况下获取索引切片;等等其他迭代功能。

    【讨论】:

    • 感谢您的解释。我一直认为 GLR 只引入了迭代 DWIMness - 保留了原始结构,但迭代动态地展平了单个元素列表。虽然实际上扁平化发生在声明阶段 - my @t = [ [ [ "a" ] ] ]; @t.push: "b"; @t.perl.say 给出了 ["a", "b"]。所以......除了在声明单个元素列表时使用尾随逗号之外,没有其他方法可以保留结构,对吧?
    • 如果有的话,我也想知道:-)
    • @raiph Itemizing 感觉像是阻止 Iterables 被迭代给我的合法方式。
    • (我忘了提)我更新了我的答案以包括 Liz++ 的建议。作为对应于 Pawel 评论的另一个示例,my @t = [ $[ $[ "a" ] ] ]; @t.push: "b"; @t.perl.say 给出了[[["a"],], "b"]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多