【问题标题】:Filling and iterating over a hash of arrays in Perl在 Perl 中填充和迭代数组的散列
【发布时间】:2012-03-22 13:39:05
【问题描述】:

我想做的是根据设备 IP 组织一堆配置参数。

对于每个 IP,都有一个索引列表 ($row),我必须生成该特定 IP 的配置。

(在这种情况下,这些索引是我的“数据”。不要将它们视为索引,它们是我必须放在那里然后在配置生成期间获取它们的东西)。

我需要“分组”的数据可能看起来像这样......

$routerIP    $row (an index to a global hash containing various details)
10.10.10.10  2
10.10.10.12  1
10.10.10.10  0
10.10.10.12  3

所以我想得到(我确实在看打印输出!)

$ipGroup{$10.10.10.10}[1] = 2
$ipGroup{$10.10.10.10}[2] = 0

$ipGroup{$10.10.10.12}[1] = 1
$ipGroup{$10.10.10.12}[2] = 3

我将%ipGroup 填充到一个循环中,该循环将通过数据:

my $routerIP = #code to get the ip
my $ind = $ipGroup{$routerIP}[0]+1;
$ipGroup{$routerIP}[0] = $ind;     
$ipGroup{$routerIP}[$ind] = $row;

在每个 IP 的数组的第 0 个元素中快速而肮脏地存储一个“当前索引”$ind 对于最新的$ind,请输入当前的$row。这样在$routerIP 键的数组中前进。

我如何在不同的子例程中读取组(%isGroup 是全局的):

foreach $routerIP (keys %ipGroup) {

    my @rows = @{$ipGroup{$routerIP}};

    my $index = 0;

    while ($rows[$index]) {
        $index++;
        my $row = $rows[$index];

    # do stuff here
    }
}

问题是:

虽然它为每个路由器IP迭代它并没有遍历所有@rows对于在哈希中的最后一个路由器

因此,使用上面的数据 id 获得 10.10.10.10 的正确配置,其中包含 $row=2$row=0 的所有内容 但是对于 10.10.10.12 id,只获取 $row=3 的配置?!

为什么它为一个键而不是另一个键迭代所有行,打印每个哈希键的数组我看到它们是不同的,我不只是在两个 $hash 值中引用了 1 个数组。 对于所有循环选项以及引用和取消引用数据结构初始化,我感到非常困惑。

填写时的代码(填写时$row命名为$hashIdprint "updated router: $routerIP index: $ind hashId: $hashId <br />";

updated router: 10.10.10.10 index: 1 hashId: 0 
updated router: 10.10.10.10 index: 2 hashId: 1 
updated router: 10.10.10.12 index: 1 hashId: 2 
updated router: 10.10.10.12 index: 2 hashId: 3 
updated router: 10.10.10.10 index: 3 hashId: 4 

填充完成后的Data Dump:

$VAR1 = {
          '10.10.10.12' => [
                               2,
                               '2',
                               '3'
                             ],
          '10.10.10.10' => [
                               3,
                               '0',
                               '1',
                               '4'
                             ]
        };

在代码的内部while循环中: print "in loop: $routerIP index: $index hashId: <br />";

in loop: 10.10.10.12 index: 1 hashId: 2 
in loop: 10.10.10.12 index: 2 hashId: 3 
in loop: 10.10.10.12 index: 3 hashId: 
in loop: 10.10.10.10 index: 1 hashId: 0 

我看到了差异,但我不知所措,为此花了几个小时。

【问题讨论】:

  • 我会说问题几乎肯定出在构建哈希的代码中。这看起来像是在 while 循环之后没有刷新最后一个数据项读取的经典案例。请展示更多导入数据的代码
  • 请同时提供散列转储:use Data::Dumper; print Dumper \%ipGroup;
  • 是的,请多多包涵,我尽量添加
  • Perl Data Structures Cookbook perldsc 中有示例。
  • 确实如此,但我已经快速完成了这项任务并且真的没有时间,仍然在掌握 perl。

标签: perl data-structures reference


【解决方案1】:

我想出了这个。它使用所有引用并且非常干净。

#!/usr/bin/perl

use strict;

# Setup a reference to a HASH
my $ipGroup = {};


# Populate your structure with __DATA__
foreach my $item (<DATA>) {

        $item =~ m/([0-9\.]+)\s(.*)/;

        # Push the "row" onto an array dynamically      
        push @{$ipGroup->{$1}}, $2;

}

foreach my $routerIP ( keys %{$ipGroup} ) {

        foreach my $row ( @{$ipGroup->{$routerIP}} ) {

                print "Doing stuff to $routerIP with index [ $row ] \n";

        }


}

我只是把你提供的数据直接放在文件里,你可能需要改一下。

__DATA__
10.10.10.10  2
10.10.10.12  1
10.10.10.10  0
10.10.10.12  3

【讨论】:

  • 这基本上就是我想要做的,是的,我现在试一试,再次使用 Perl 语法魔法,同时又爱又恨啊。
  • 很高兴为您提供帮助。祝你有美好的一天。
  • 在进行任何其他操作之前,您应该在任何时候进行匹配时测试结果正则表达式。您可能在源文件中有一行与正则表达式不匹配,然后您将前一行的 $2 再次推送到 @{$ipGroup->{$1}} 中。
猜你喜欢
  • 1970-01-01
  • 2010-12-04
  • 1970-01-01
  • 1970-01-01
  • 2017-02-21
  • 2012-08-03
  • 1970-01-01
  • 2014-08-31
  • 2012-12-01
相关资源
最近更新 更多