Perl 填充HoH,其外部哈希键位于一个数组中,而内部哈希值位于另一个数组中

Perl 填充HoH,其外部哈希键位于一个数组中,而内部哈希值位于另一个数组中,perl,data-structures,Perl,Data Structures,解释 一个数组包含一组键。这些键的值是内部哈希。在本例中,这些内部哈希的键是数字(类似于数组索引)。另一个数组保存内部散列的值 问题: 如何用正确的对应值(即正确的内部哈希)填充外部哈希键 合同 我更喜欢使用切片、贴图或grep的解决方案。消除循环的级联 我意识到这应该是个骗局。但这只是供我学习的,它没有任何功能价值 工作代码: 这段代码可以按照我的要求工作,但我想使用更高级的技术: #! usr/bin/perl use strict; use warnings; use Data::Dum

解释

一个数组包含一组键。这些键的值是内部哈希。在本例中,这些内部哈希的键是数字(类似于数组索引)。另一个数组保存内部散列的值

问题:

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

合同

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

我意识到这应该是个骗局。但这只是供我学习的,它没有任何功能价值

工作代码

这段代码可以按照我的要求工作,但我想使用更高级的技术:

#! 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\u class\u student\u names,\@Math\u class\u student\u names);
但还没有取得任何进展。

一次只处理一层比较容易。对于内层,似乎你想要

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
   };
}

一次只处理一层比较容易。对于内层,似乎您需要

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\u class'=>\@Science\u class\u学生的名字(我必须使用if-else进行命名)?这似乎是不可能的。哇!找到答案了(只要它们以相同的顺序输入):
my%classhash;
@classhash{@classNames}=@studentNames;
注意:(
@studentNames
是AoA,如问题的Ideas部分所示)。然后将for循环替换为:
for(键%classhash){
并替换声明:
我的$class\u name=$\uu;我的$student\u name=$classhash{$\u};
非常好的答案,感谢您给出了思考过程。我的一个问题是:外层是否可以通用化,而不必为每个“类”键入:
'Science\u class'=>\@Science\u class\u student\u name
(这是我必须使用if-else做的)?这似乎不可能。呼!算出了(只要它们以相同的顺序输入):
my%classhash;
@classhash{@classNames}=@studentNames;
注意:(
@studentNames
是AoA,如问题的Ideas部分所示)。然后将for循环替换为:
for(键%classhash){
并替换声明:
my$class\u name=$\uu;my$student\u name=$classhash{$\u};