迭代具有多个索引的哈希中的哈希数组

时间:2015-06-11 03:42:54

标签: arrays perl loops hash hashmap

我目前正在编写一个perl脚本,其中包含一些包含以下内容的哈希: (不要把它作为代码行,只是为了显示/解释)

$details{tester_name} is "UFLEX-06"
$details{op_sys} is "Windows"
$details{igxl_vn} is "8.00.01_uflx (P7)"
$details{slot} -> see below for details
$details{board_name} -> see below for details

现在在$ details {slot}中我有多个索引,每个索引包含一个值。

$details{slot} [0] has "2"
$details{slot} [1] has "5"

等等。 $ details {slot}与$ details {board_name} 的索引数相同。

现在我想迭代这个但是根据$ details {slot}

到目前为止,我所做的只是%详细信息

foreach my $key(keys %details)
{
    print {$fh} "INSERT INTO TesterDeviceMatrix.TBL_TESTER_INFO"
    ."(tester_name, operating_system , version, board_name , config , date_modified ) "
    ."VALUES ('$details{tester_name}', '$details{op_sys}', '$details{board_name}', "
    ."'$details{igxl_vn}', '$details{slot}', '$timestamp');\n";
}

但我想做的是像

foreach my $key(keys %details{slot}) -> or %details{board_name}
{
    print {$fh} "INSERT INTO TesterDeviceMatrix.TBL_TESTER_INFO"
    ."(tester_name, operating_system , version, board_name , config , date_modified ) "
    ."VALUES ('$details{tester_name}', '$details{op_sys}', '$details{board_name}', "
    ."'$details{igxl_vn}', '$details{slot}', '$timestamp');\n";
}

我知道这是错的,但只是为了表明我的想法。

我现在得到的输出是:

INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'VirtualDSPBrd', '8.00.01_uflx (P7)', '66.0', '2015-06-11 11:15:33');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'VirtualDSPBrd', '8.00.01_uflx (P7)', '66.0', '2015-06-11 11:15:33');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'VirtualDSPBrd', '8.00.01_uflx (P7)', '66.0', '2015-06-11 11:15:33');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'VirtualDSPBrd', '8.00.01_uflx (P7)', '66.0', '2015-06-11 11:15:33');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'VirtualDSPBrd', '8.00.01_uflx (P7)', '66.0', '2015-06-11 11:15:33');

上面的输出有5行,因为有5个哈希。然而我想要的是 8行,其值根据其索引,因为$details{slot}有8个索引,这意味着$details{board_name}还有8个索引。

我想要的输出的一个例子是(注意值差异和8行):

INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'abcBrd', '8.00.01_uflx (P7)', '2.0', '2015-06-11 11:15:33');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'VqwelDSPBrd', '8.00.01_uflx (P7)', '5.0', '2015-06-11 11:15:33');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'DiffDSPBrd', '8.00.01_uflx (P7)', '8.0', '2015-06-11 11:15:33');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', '123DSPBrd', '8.00.01_uflx (P7)', '26.0', '2015-06-11 11:15:33');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'V1r12alDSPBrd', '8.00.01_uflx (P7)', '56.0', '2015-06-11 11:15:33');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'VMamaBrd', '8.00.01_uflx (P7)', '52.0', '2015-06-11 11:15:33');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'ONSPBrd', '8.00.01_uflx (P7)', '56.0', '2015-06-11 11:15:33');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'bankaiPBrd', '8.00.01_uflx (P7)', '66.0', '2015-06-11 11:15:33');

所以问题是如何迭代然后根据哈希$details{slot}中的索引数量进行打印,其中$details{slot}$details{board_name}将根据其索引打印?< / p>

据我所知,我必须在当前的循环中创建另一个for循环。但是,大多数解决方案都适用于仅包含一个值的哈希值,这就是为什么它不能满足我的需求。

编辑:

(注意:此转储仅显示最新的board_nameslot

{
    board_name => "Virtualabc"
    igxl_vn => "9.0.0_abc"
    op_sys => "Windows"
    slot => "66.0"
    tester_name => "UNFEK-02"
}

编辑2:

我编辑了我的脚本,我按照@shivams的建议将slotboard_name声明为数组。

push @{ $details{slot} }, [$1];
push @{ $details{board_name} }, [$2];

现在正如Dmitry的回答(第一部分)所建议的,我只得到对数组的引用。这是输出:

INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'ARRAY(0x1d2fb98) [0]', '8.00.01_uflx (P7)', 'ARRAY(0x1d40288) [0]', '2015-06-11 15:18:37');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'ARRAY(0x1d2fb98) [1]', '8.00.01_uflx (P7)', 'ARRAY(0x1d40288) [1]', '2015-06-11 15:18:37');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'ARRAY(0x1d2fb98) [2]', '8.00.01_uflx (P7)', 'ARRAY(0x1d40288) [2]', '2015-06-11 15:18:37');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'ARRAY(0x1d2fb98) [3]', '8.00.01_uflx (P7)', 'ARRAY(0x1d40288) [3]', '2015-06-11 15:18:37');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'ARRAY(0x1d2fb98) [4]', '8.00.01_uflx (P7)', 'ARRAY(0x1d40288) [4]', '2015-06-11 15:18:37');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'ARRAY(0x1d2fb98) [5]', '8.00.01_uflx (P7)', 'ARRAY(0x1d40288) [5]', '2015-06-11 15:18:37');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'ARRAY(0x1d2fb98) [6]', '8.00.01_uflx (P7)', 'ARRAY(0x1d40288) [6]', '2015-06-11 15:18:37');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'ARRAY(0x1d2fb98) [7]', '8.00.01_uflx (P7)', 'ARRAY(0x1d40288) [7]', '2015-06-11 15:18:37');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'ARRAY(0x1d2fb98) [8]', '8.00.01_uflx (P7)', 'ARRAY(0x1d40288) [8]', '2015-06-11 15:18:37');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'ARRAY(0x1d2fb98) [9]', '8.00.01_uflx (P7)', 'ARRAY(0x1d40288) [9]', '2015-06-11 15:18:37');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'ARRAY(0x1d2fb98) [10]', '8.00.01_uflx (P7)', 'ARRAY(0x1d40288) [10]', '2015-06-11 15:18:37');
INSERT INTO TBL_TESTER_INFO(tester_name, operating_system , version, board_name , config , date_modified ) VALUES ('UFLEX-06', 'Windows XP', 'ARRAY(0x1d2fb98) [11]', '8.00.01_uflx (P7)', 'ARRAY(0x1d40288) [11]', '2015-06-11 15:18:37');

我如何获得确切的值?

2 个答案:

答案 0 :(得分:1)

foreach my $key(keys %details) {
 if (ref($key)  eq 'ARRAY') {
   foreach $key2 (@$key) {
      PRINT STATEMENT
   }
 }
 else {
  PRINT STATEMENT
 }
}

这样,当哈希中有数组时,你的代码将通过内部foreach循环在该数组上循环,否则它将转到else。现在也是你想如何使用我完全依赖你的价值。

答案 1 :(得分:1)

您实际上不需要遍历keys %details。我认为,你根据鲍罗丁的Extracting data from log file into Perl hash建议构建了%details哈希。在这种情况下,你所拥有的实际上并不是一个哈希数组,而是一个包含两个列表的哈希%details(在其他一些标量值中)。

为了从中准备所需的插入语句集,您应该只遍历%details的子列表。应直接访问%details的标量字段:

for (my $i = 0; $i < @{$details{slot}}; $i++) {
    print
        "INSERT INTO TesterDeviceMatrix.TBL_TESTER_INFO"
        ."(tester_name, operating_system , version, board_name , config , date_modified ) "
        ."VALUES ('$details{tester_name}', '$details{op_sys}', '$details{board_name}[$i]', "
        ."'$details{igxl_vn}', '$details{slot}[$i]', '$timestamp');\n";
}

Here是一个测试脚本,说明了上述情况。

编辑后的更新2:

更改

push @{ $details{slot} }, [$1];
push @{ $details{board_name} }, [$2];

push @{ $details{slot} }, $1;
push @{ $details{board_name} }, $2;

[$var](即带方括号的标量变量)推入数组将使用包含此单个标量值的单元素子阵列填充数组。这是因为[$var]构造了对包含单个元素$var的数组的引用。实际上你需要的只是推动标量值本身。

P.S。

考虑使用参数化查询而不是硬编码查询。