【问题标题】:Initialize empty Array of Hashes of a given length - one-liner初始化给定长度的空哈希数组 - 单行
【发布时间】:2019-02-28 14:27:39
【问题描述】:

我想预先初始化散列数组的元素,以便在填充数据时,我不需要检查各种成员的存在并在每个循环中初始化它们。如果可以的话,我想预初始化数据结构的一般形式,应该如下所示:

$num_sections = 4;
# Some magic to initialize $VAR1 to this:
$VAR1 = {
          'sections' => [
                          {},
                          {},
                          {},
                          {}
                        ]
        };

我希望这个工作,

$ph->{sections} ||= [({} x $num_sections )];

但它会导致

$VAR1 = {
          'sections' => 'HASH(0x21b6110)HASH(0x21b6110)HASH(0x21b6110)HASH(0x21b6110)'
        };

不管怎么玩() 列表上下文和{} 空哈希引用似乎都无法正常工作。

这可行,但它并不完全是单线

unless ($ph->{sections})
{
    push @{ $ph->{sections}}, {} foreach (1..$num_sections);
}

可能有一些 perl 魔法可以用来将 unless 添加到末尾,但我还没有完全弄清楚。

我觉得我很接近,但我就是无法完全理解。

更新 Oleg 指出这可能根本没有必要。请参阅下面的 cmets。

【问题讨论】:

  • 你确定你甚至需要预初始化任何东西吗?你能展示“填充”部分来说明为什么简单的自动复活是不够的吗?
  • @OlegV.Volkov,我认为你是对的。我总是担心 perl 中复杂数据结构的自动激活,但我只是尝试过,它工作正常:my $test; $test->{sections}->[3]->{happy}= 'true'; 我想也许这是过去我想push 到一个显然有的列表的情况首先要初始化为一个空列表,而我错误地将其概括为“如果不预先初始化它,就无法访​​问数据结构的深层成员。

标签: perl


【解决方案1】:

如果x 的左侧不在括号中,x 在其 LHS 上重复 字符串 并返回这些字符串的串联。

如果x 的左侧在括号中,x 在其 LHS 上重复该值并返回副本。

后一种方法更接近你想要的,但它仍然是错误的,因为你最终会得到对单个哈希的多个引用。您不仅要创建新的引用,还要创建新的哈希值。为此,您可以使用以下内容:

$ph->{sections} ||= [ map { +{} } 1..$num_sections ];

【讨论】:

  • 太棒了。 + 有什么作用?
  • 它确保{} 被解释为一个哈希构造函数而不是一个裸循环。不知道这里有没有必要。请参阅here 以获得更详尽的说明。
  • x 的描述仅适用于列表上下文;在标量上下文中,x 总是返回重复字符串的串联
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-29
  • 2016-06-17
  • 2015-06-08
  • 1970-01-01
  • 1970-01-01
  • 2016-10-24
  • 1970-01-01
相关资源
最近更新 更多