【问题标题】:Perl 5.26: How to get keys from 2d hash?Perl 5.26:如何从二维哈希中获取密钥?
【发布时间】:2020-02-03 18:49:47
【问题描述】:

系统:Ubuntu 18.04 上的 Perl 5.26.1。

我们将 Ubuntu 升级到 18.04,将 Perl 升级到 5.26,现在不再支持我在 Perl 5.18 中使用二维哈希的实验方式。这是我使用实验性东西的错。

我的目标:我正在尝试使用新的方法来做散列的散列,或 2 个键的散列,或 2d 散列。 IE。一个哈希有 2 个键,一个部门,每个部门都有一个或多个员工 ID。哈希中也可以有多个部门作为第一个键。我正在从 SQL 语句的结果中读取数据,因此我必须为每个员工 ID 添加小时数。部分问题是我先读了部门,然后我得到了empid。

问题:我在获取 empid 的第二个循环中遇到错误。运行时错误是:“在使用“严格引用”时,不能使用字符串 (“6”) 作为 HASH 引用”。

  • 我一直在进行研究,但找不到适合我的案例的具体示例,示例与我正在做的不同,或者我尝试的示例不起作用并给我一个错误。
  • 我读过的页面中至少有一半没有日期,所以我什至无法猜测它们是用于什么版本的 perl。
  • 关于此主题的 perldocs 与我在 Internet 上找到的其他页面相同。
  • 我不能只为这份报告使用简单的 SQL 语句,因为在获得每个员工的数据后,我必须做更多的处理。
  • 我尝试了几种代码排列,但都没有成功。但我在这里排除了这些排列。
  • 出于某种原因,我在 Internet 上找到的大多数示例都不适用于 Perl 5.26。

这是我的代码。我已经尝试了来自不同来源的几种排列以使其正常工作。

use strict;
use warnings;


use Data::Dumper;

####################
# Variables
my $i=0;
my $s='';
my $t='';
my $k='';
my $k2='';
my $empid='';
my $z='';
my @k=(); # Key list
my @k2=(); # Key list

my %hashs=(); # Scalar hash, works.
my %empees=();
my $pos=0;
my $val="Myval";
my $dept='';

####################
$s="Data::Dumper $Data::Dumper::VERSION";
print "$s\n";
print "\n";

$empees{'JSMITH'}=1.0; # WORKS
$empees{'RGREEN'}=2.0;
$empees{'KJONES'}=3.0;
$hashs{950}=%empees;

$empees{'WSMIT'}=1.5;
$empees{'AMCBE'}=2.5;
$empees{'SCHWAR'}=3.5;
$hashs{800}=%empees;

# Now print out values in 2d hash.
@k=keys(%hashs);
print "Keys and values are:\n";
foreach $dept (sort keys %hashs)
    {
    for $empid (sort keys %{$hashs{$dept}} ) # ERROR is here
        {
        $val=$hashs{$dept}{$empid};
        $t="$dept $empid $val";
        print "$t\n";
        } # foreach $empid
    } # foreach $dept
  • 有人可以帮我吗?
  • 除了散列哈希之外,还有其他方法可以完成此任务吗?

感谢您的所有帮助!非常感谢您的宝贵时间!

【问题讨论】:

  • 你之前在做什么?自 Perl 5.0 以来,执行此操作的常用方法已基本修复。
  • 此代码:$hashs{950}=%empees 不符合您的想法?它分配的值等于%empees 中的键数。

标签: perl hashmap


【解决方案1】:

这个 sn-p 对我有用

$hashs{950}=\%empees;

$empees{'WSMIT'}=1.5;
$empees{'AMCBE'}=2.5;
$empees{'SCHWAR'}=3.5;
$hashs{800}=\%empees;

# Now print out values in 2d hash.
@k=keys(%hashs);
print "Keys and values are:\n";
for my $dept (sort keys %hashs) {
    for my $empid (sort keys %{$hashs{$dept}}) {
        print "$empid\n";
        $val=$hashs{$dept}{$empid};
        $t="$dept $empid $val";
        print "$t\n";
    } # foreach $empid
} # foreach $dept

【讨论】:

  • 谢谢。在我标记答案之前,我必须用这个哈希尝试一些其他的东西,重写一些子例程,测试将参数传递给一个子例程。
  • 感谢您帮助我理解这一点,现在我明白我做错了什么,我可以将这种理解应用于未来的问题。您将一行更正为 $hashs{800}=\%empees 的地方有很大帮助。
【解决方案2】:

哈希值始终是标量。

所以,而不是分配一个哈希

$hashs{950}=%empees;

分配一个哈希引用:

$hashs{950} = { %empees };

这仅在 %empees 是一级哈希时有效,否则您需要进行深层复制,例如

use Storable qw{ dclone };
# ...
$hashs{950} = dclone(\%empees);

对于 800 也是如此(您可能需要清空 %empees,否则您也将分配已分配给 950 的值)。

或者,直接赋值:

$hashs{950} = { JSMITH => 1.0,
                RGREEN => 2.0,
                KJONES => 3.0 };

【讨论】:

  • $hashs{950} = { %empees }; 会将整个哈希复制到一个新哈希中,并获取新哈希的引用。如果您不想要副本,请使用$hashs{950} = \%empees;
  • @ChristofferHammarström:但是随后将 %empees 更改为填充 $hashs{800} 也会更改已存储的数据。
  • 对,我只是指出来。像您建议的那样直接分配它会更好。
  • 哈希引用{ %empees } 是浅拷贝。更改某些值可能仍会更改原始值。 Storable 的dclone 可以完全解耦。
【解决方案3】:

OP 的问题并未完全涵盖该问题。

请看下面这段代码,它演示了如何用数据填充散列部门,以及如何检索这些数据以供以后使用。

use strict;
use warnings;
use feature 'say';

use Data::Dumper;

my $debug = 1;

my %departments;
my $department;

while( <DATA> ) {
    $department = $1 if /^(\d+)/;
    $departments{$department}{$1}=$2 if /^\s+(\w+):([\d\.]+)/;
}

say Dumper(\%departments) if $debug;

foreach $department (sort keys %departments) {
    say $department;
    foreach my $employee (sort keys %{$departments{$department}}) {
        say "\t $employee $departments{$department}{$employee}";
    }
}

__DATA__
950
    JSMITH:1.0
    RGREEN:2.0
    KJONES:3.0
800
    WSMIT:1.5
    AMCBE:2.5
    SCHWAR:3.5

输出

$VAR1 = {
          '950' => {
                     'JSMITH' => '1.0',
                     'KJONES' => '3.0',
                     'RGREEN' => '2.0'
                   },
          '800' => {
                     'WSMIT' => '1.5',
                     'SCHWAR' => '3.5',
                     'AMCBE' => '2.5'
                   }
        };

800
         AMCBE 2.5
         SCHWAR 3.5
         WSMIT 1.5
950
         JSMITH 1.0
         KJONES 3.0
         RGREEN 2.0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 2015-02-08
    • 2013-04-19
    • 1970-01-01
    • 2012-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多