【问题标题】:Populating a HoH, whose outer hash keys are in one array, and inner hash values are in another填充一个 HoH,其外部哈希键在一个数组中,而内部哈希值在另一个数组中
【发布时间】:2011-10-03 18:50:42
【问题描述】:

说明

一个数组包含一组键。这些键的值是内部散列。这些内部哈希的键,在这种情况下是数字(如数组索引)。另一个数组保存内部哈希的值。

问题:

如何使用正确的对应值(即正确的内部哈希)填充外部哈希键?

约束

我更喜欢使用切片、映射或 grep 的解决方案。消除级联 for 循环

我意识到它应该是一个 HoA。不过这个仅供我学习,没有任何功能价值……

工作代码

此代码可以按我的意愿工作,但我想使用更高级的技术:

#! usr/bin/perl

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

my %register=();

my @classNames = ('Science_class', 'Math_class');
my @Science_class_student_names = ('George', 'Lisa', 'Mathias'); #prob from file
my @Math_class_student_names = ('Martin', 'Anna', 'Peter', 'George'); #prob from file

foreach my $className (@classNames) {
    my $array_name = $className.'_'.'student_names';
    if ($array_name =~ /Science/) {
        foreach (0..$#Science_class_student_names ) {
            $register{$className}{$_ + 1} = $Science_class_student_names[$_];
        }
    }
    elsif ($array_name =~ /Math/) {
        foreach (0..$#Math_class_student_names ) {
            $register{$className}{$_ + 1} = $Math_class_student_names[$_];
        }
    }
}

print Dumper(\%register);

想法

哈希片适用于直接键值对,但中间键让我失望。尝试类似:@register{@classNames} = map{$count => $student}

在 if 语句之前,我有一个想法是如果有一种方法可以在数组名称中使用字符串:$#($array_name)student_names,但这不起作用。

另一种方法是分别创建一个包含所有内部哈希键的数组,使用切片,然后将该哈希放入外部哈希中。

我唯一的另一个想法是使用 AoA 来保存所有“内部哈希值”数组。 (即my @studentNames = (\@Science_class_student_names, \@Math_class_student_names);,但还没有得到任何结果。

【问题讨论】:

    标签: perl data-structures


    【解决方案1】:

    一次处理一层更容易。对于内层,看来你想要

    1 => George,
    2 => Lisa,
    ...
    

    所以首先要弄清楚如何做到这一点。

    map { $_+1 => $Science_class_student_names[$_] }
       0..$#Science_class_student_names
    

    所以你最终得到了

    $register{'Science_class'} = {
       map { $_+1 => $Science_class_student_names[$_] }
          0..$#Science_class_student_names
       }
    };
    
    $register{'Math_class'} = {
       map { $_+1 => $Math_class_student_names[$_] }
          0..$#Math_class_student_names
       }
    };
    

    如果你概括内层,你会得到

    for (
       [ 'Science_class' => \@Science_class_student_names ],
       [ 'Math_class'    => \@Math_class_student_names ],
    ) {
       my ($class_name, $student_names) = @$_;
       $register{$class_name} = {
          map { $_+1 => $student_names->[$_] }
             0..$#$student_names
       };
    }
    

    【讨论】:

    • 很好的答案,感谢您提供思考过程。我的一个问题是:可以概括外层,而不必为每个“类”键入:'Science_class' => \@Science_class_student_names(我必须使用 if-else)?这似乎是不可能的。
    • 哇!想通了(只要它们以相同的顺序输入):my %classhash;@classhash{@classNames} = @studentNames;注意:(@studentNames 是 AoA,如问题的想法部分所示)。然后将您的 for 循环替换为:for (keys %classhash) { 并替换声明:my $class_name = $_; my $student_names = $classhash{$_};
    猜你喜欢
    • 1970-01-01
    • 2019-05-01
    • 2013-05-17
    • 2019-07-30
    • 1970-01-01
    • 1970-01-01
    • 2014-04-18
    • 1970-01-01
    • 2018-11-04
    相关资源
    最近更新 更多