Perl 5.26: Как получить ключи от 2д га sh? - PullRequest
2 голосов
/ 31 января 2020

Система: Perl 5.26.1 в Ubuntu 18.04.

Мы обновили нашу Ubuntu до 18.04 и Perl до 5.26, и теперь экспериментальный способ использования 2d хэшей в Perl 5.18 - нет дольше поддерживается. Это моя вина за использование чего-то экспериментального.

Моя цель : я пытаюсь по-новому использовать ха sh хешей, или ха sh из 2 ключей, или 2d га sh , Т.е. ха sh будет иметь 2 ключа, отдел, и каждый отдел будет иметь один или несколько идентификаторов сотрудников. В ha sh также может быть много отделов в качестве первого ключа. Я читаю данные из результатов оператора SQL, поэтому мне нужно добавить часы для каждого сотрудника. Отчасти проблема в том, что я сначала читаю отдел, затем получаю empid.

Проблема : в секунду я получаю сообщение об ошибке, чтобы получить empid. Ошибка времени выполнения: «Невозможно использовать строку (« 6 ») в качестве ссылки HA SH, пока используются« строгие ссылки ».

  • Я проводил исследования и могу Не могу найти конкретный пример c для моего случая, примеры отличаются от того, что я делаю, или примеры, которые я пробую, не работают и выдают мне ошибку.
  • По крайней мере половина страниц, которые я прочитал, не имеет даты, поэтому я даже не могу догадаться, для какой версии perl они предназначены.
  • Perldocs на этой топи c такие же, как и другие страницы, которые я нашел в inte rnet.
  • Я не могу просто использовать простое утверждение SQL для этого отчета, потому что мне нужно сделать намного больше обработки после того, как я получу данные для каждого сотрудника.
  • Я пробовал несколько перестановок кода без удачи. Но я исключаю эти перестановки здесь.
  • Большинство примеров, которые я нашел в inte rnet, не работают с 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
  • Может кто-нибудь помочь мне здесь?
  • Есть ли другой способ сделать это, кроме ха sh хешей?

Спасибо за вашу помощь! Я очень ценю ваше время!

Ответы [ 3 ]

2 голосов
/ 31 января 2020

Этот фрагмент работает для меня

$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
0 голосов
/ 01 февраля 2020

Вопрос ОП не охватывает проблему в полной мере.

Пожалуйста, посмотрите следующий фрагмент кода, который демонстрирует, как ха sh отделы могут быть заполнены данными и как эти данные могут быть получены для последующего использования.

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
0 голосов
/ 31 января 2020

Значение га sh всегда является скаляром.

Таким образом, вместо присвоения ха sh

$hashs{950}=%empees;

назначаем га sh ссылка:

$hashs{950} = { %empees };

Это работает, только если% empees имеет одноуровневый ха sh, в противном случае вам нужно сделать глубокую копию, например,

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

и аналогично для 800 (вам, вероятно, нужно чтобы очистить% empees, в противном случае вы бы также присвоили значения, уже присвоенные 950).

Или назначьте его напрямую:

$hashs{950} = { JSMITH => 1.0,
                RGREEN => 2.0,
                KJONES => 3.0 };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...