【问题标题】:How can I elegantly create a hash from an array reference in Perl?如何从 Perl 中的数组引用优雅地创建散列?
【发布时间】:2010-10-29 02:07:10
【问题描述】:

我正在寻找一种更优雅的方法来创建包含我从配置文件中读取的列表的哈希。这是我的代码:

read_config($config_file => my %config);

my $extension_list_reference = $config{extensions}{ext};

my @ext;

# Store each item of the list into an array

for my $i ( 0 .. (@$extension_list_reference - 1) ) {
    $ext[$i] = $extension_list_reference->[$i];
}

# Create hash with the array elements as the keys

foreach my $entry (@ext) {
    $extensions{$entry} = "include";
 }   

谢谢。

【问题讨论】:

  • 我将为您提供怀疑的好处,并假设您只是忘记包含“使用严格;”和“使用警告;”这肯定在您的代码的顶部。
  • 当我第一次了解到 Perl 时,我发现的最令人沮丧的事情之一是默认情况下没有启用 strict。为了完整起见,我会把它们扔进去。
  • 哦等等,这不是我的问题。这是尼尔的其他问题。哎呀!
  • 我们应该做点什么,让我们所有的“尼尔”都不会感到困惑!可以更新我们的名字吗?我可以建议你成为“布鲁克林尼尔”,我会成为“D.C.尼尔”。

标签: perl arrays hash reference


【解决方案1】:

尝试使用地图: http://perldoc.perl.org/functions/map.html

您的新代码应如下所示:

my %extensions = map { $_ => "include" } @{ $config{extensions}{ext} };

【讨论】:

  • 谢谢。布鲁克林怎么样?我的出生地。
  • 不错,4个月前刚搬到这里。
  • 我的 %extensions = map { $_ => "include" } @{ $config{extensions}{ext} }
  • 感谢 Kent 的重构。
【解决方案2】:

my %hash = map { $_ => 'include' } @list;

【讨论】:

  • 以下工作:%extensions = map {$_ => "include" } @$extension_list_reference;
【解决方案3】:

如果我理解你的问题,这就是你如何在一行中做到的:

@extensions{@$extension_list_reference} = ();

注意:hash的每个值都是空的,但是你仍然可以使用函数exists来检查key是否存在于hash中,像这样:

if(exists $extensions{$some_key}) {...

附:如果由于某种原因您确实需要将这些字符串“包含”作为值,您也可以拥有它们:

@extensions{@$extension_list_reference} = ('include') x @$extension_list_reference;

【讨论】:

  • 为什么这个工作而不是:%extensions{@$extension_list_reference} = (); ?
  • 因为你在一个'hash slice'上操作:perldoc.perl.org/perldata.html#Slices
  • 当列表有多个值时,这可以正常工作。有人可能在他们的配置文件中只有一个值。我如何处理一个值与多个值?
  • 很抱歉,如果列表仅包含一项,我忘记包含我收到的错误消息:Can't use string (".frames") as an ARRAY ref while "strict refs" in在 create_video_frames.pl 第 209 行 (#1) (F) 使用“严格引用”仅允许硬引用。不允许使用符号引用。见 perlref。用户代码中未捕获的异常:在 create_video_frames.pl 第 209 行使用“strict refs”时,不能使用字符串(“.frames”)作为 ARRAY 引用。在 create_video_frames.pl 第 209 行
  • 您可以使用 ref 函数检查 $extension_list_reference 指向的内容。所以 $extension_list_reference = ref $extension_list_reference ? $extension_list_reference : [ $extension_list_reference ];应该这样做。
【解决方案4】:

这边:

read_config($config_file => my %config);
%extensions = map +($_ => "include"), @{$config{extensions}{ext}};

或者这样:

read_config($config_file => my %config);
@extensions{@{$config{extensions}{ext}}} = ("include") x @{$config{extensions}{ext}};

【讨论】:

  • 我喜欢这种方法 - 谢谢。
猜你喜欢
  • 2010-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-13
  • 1970-01-01
  • 2014-01-16
相关资源
最近更新 更多