【问题标题】:How to slice only defined values?如何只切片定义的值?
【发布时间】:2023-03-16 02:06:01
【问题描述】:

我可以将 kes/values 切片为下一个:

$item->%{ @cols }

但如果$item 处不存在某些列,它将在结果哈希处创建。

我可以只切片定义的值吗?

【问题讨论】:

  • 你试过no autovivification;吗?
  • @tobyink,问题不在于自动生存,而是在意外将哈希元素用作左值时创建哈希元素。 no autovivification; 无济于事。

标签: perl perl-data-structures


【解决方案1】:

你可以检查它们是否存在。

$item->%{ grep {exists $item->{$_}} @cols }

应该只对现有值进行切片。

无论如何 - 简单地访问这些值不应该自动激活它们。只有当您将这些值作为参数传递给某个函数并且它们在那里隐含别名时,它们才会自动激活。

use strict;
use warnings;
use Data::Dumper;

my @cols =qw (a b c);
my $item = [{a => 1, c => 3}];

print Dumper({$item->[0]->%{ grep {exists $item->[0]->{$_}} @cols }});
print Dumper($item);

print Dumper({$item->[0]->%{ @cols }});
print Dumper($item);

print Dumper($item->[0]->%{ grep {exists $item->[0]->{$_}} @cols });
print Dumper($item);

print Dumper($item->[0]->%{ @cols }); ## Only here does autovivication take place
print Dumper($item);

只有最后一次打印会生成:

$VAR1 = [
          {
            'c' => 3,
            'a' => 1,
            'b' => undef
          }
        ];

表示 b 已自动激活。

【讨论】:

  • 在例子中->[0]似乎是多余的
  • 我(在示例脚本中)将 $item 定义为一个哈希数组,只是为了表明这适用于任何复杂的数据结构。
【解决方案2】:

使用

$item->%{ grep { exists($item->{$_}) } @cols }

或

do { $item->%{ @cols } }

索引/切片哈希不会向其中添加元素。

my @cols = qw( a b c );
my $item = { };
say 0+%$item;                     # 0
my @kvs = $item->%{ @cols };
say 0+%$item;                     # 0 ok

除非它用作左值(可赋值,例如在= 的左侧)。

my @cols = qw( a b c );
my $item = { };
say 0+%$item;                     # 0
1 for $item->%{ @cols };
say 0+%$item;                     # 3 XXX

您可以过滤掉不存在的元素的键。

my @cols = qw( a b c );
my $item = { };
say 0+%$item;                     # 0
1 for $item->%{ grep { exists($item->{$_}) } @cols };
say 0+%$item;                     # 0 ok

但简单的解决方案是不要将其用作左值。

my @cols = qw( a b c );
my $item = { };
say 0+%$item;                     # 0
1 for do { $item->%{ @cols } };
say 0+%$item;                     # 0 ok

【讨论】:

    猜你喜欢
    • 2015-05-21
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    • 1970-01-01
    • 2014-08-20
    • 2017-02-05
    • 2020-06-25
    • 1970-01-01
    相关资源
    最近更新 更多