如果两个键相同但值不同,谁能解释如何打印所有键?

Ale*_*exx 9 string perl hash

在这段代码中,两个键“39”同名但值不同,我想打印两个键

use strict; 
use warnings; 

my %studentnames = ( 
14 => Martha, 
27 =>Vivek, 
31 =>Era, 
16 =>Marty, 
25 =>Jason, 
29 =>Socrates, 
19 =>Uri, 
39 =>Nitin , 
39 =>Plato, 
); 

foreach my $name (sort keys %studentnames) 
{ 
    printf "%-8s %s\n", $name, $studentnames{$name};
} 
Run Code Online (Sandbox Code Playgroud)

我收到错误。

Bareword "Martha" not allowed while "strict subs" in use at /home/9945b48d30946ed2641d9778b42cb182.pl line 10.
Bareword "Vivek" not allowed while "strict subs" in use at /home/9945b48d30946ed2641d9778b42cb182.pl line 10.
Bareword "Era" not allowed while "strict subs" in use at /home/9945b48d30946ed2641d9778b42cb182.pl line 10.
Bareword "Marty" not allowed while "strict subs" in use at /home/9945b48d30946ed2641d9778b42cb182.pl line 10.
Bareword "Jason" not allowed while "strict subs" in use at /home/9945b48d30946ed2641d9778b42cb182.pl line 10.
Bareword "Socrates" not allowed while "strict subs" in use at /home/9945b48d30946ed2641d9778b42cb182.pl line 10.
Bareword "Uri" not allowed while "strict subs" in use at /home/9945b48d30946ed2641d9778b42cb182.pl line 10.
Bareword "Nitin" not allowed while "strict subs" in use at /home/9945b48d30946ed2641d9778b42cb182.pl line 10.
Bareword "Plato" not allowed while "strict subs" in use at /home/9945b48d30946ed2641d9778b42cb182.pl line 10.
Run Code Online (Sandbox Code Playgroud)

预期产出

14   Martha
27   Vivek 
31   Era
16   Marty 
25   Jason 
29   Socrates 
19   Uri
39   Nitin 
39   Plato
Run Code Online (Sandbox Code Playgroud)

谁能告诉我怎么做?

Que*_*tin 9

两个键不能相同。一个会覆盖另一个。如果您想为一个键设置多个值,那么您需要设计您的数据结构来支持这一点(例如,将值设为一个数组引用)。

您的错误消息与该问题无关(您忘记在字符串值周围加上引号)。


tob*_*ink 6

这有点接近:

use strict;
use warnings;
use Tie::Hash::MultiValueOrdered;

tie my %studentnames, 'Tie::Hash::MultiValueOrdered';
%studentnames = (
    14 => 'Martha',
    27 => 'Vivek',
    31 => 'Era',
    16 => 'Marty',
    25 => 'Jason',
    29 => 'Socrates',
    19 => 'Uri',
    39 => 'Nitin',
    39 => 'Plato',
); 

tied(%studentnames)->fetch_list;

while ( my ( $key, $value ) = each %studentnames ) {
    print "$key => @$value\n";
}
Run Code Online (Sandbox Code Playgroud)

但实际上您想使用不同的数据结构。也许是一个arrayrefs数组?

use strict;
use warnings;

my @students = (
    [ 14 => 'Martha'   ],
    [ 27 => 'Vivek'    ],
    [ 31 => 'Era'      ],
    [ 16 => 'Marty'    ],
    [ 25 => 'Jason'    ],
    [ 29 => 'Socrates' ],
    [ 19 => 'Uri'      ],
    [ 39 => 'Nitin'    ],
    [ 39 => 'Plato'    ],
); 

for my $student ( @students ) {
    my ( $num, $name ) = @$student;
    print "$num => $name\n";
}
Run Code Online (Sandbox Code Playgroud)

或者一个 hashrefs 数组:

use strict;
use warnings;

my @students = (
    { num => 14 , name => 'Martha'   },
    { num => 27 , name => 'Vivek'    },
    { num => 31 , name => 'Era'      },
    { num => 16 , name => 'Marty'    },
    { num => 25 , name => 'Jason'    },
    { num => 29 , name => 'Socrates' },
    { num => 19 , name => 'Uri'      },
    { num => 39 , name => 'Nitin'    },
    { num => 39 , name => 'Plato'    },
); 

for my $student ( @students ) {
    print "$student->{num} => $student->{name}\n";
}
Run Code Online (Sandbox Code Playgroud)

或 arrayrefs 的散列:

use strict;
use warnings;

my %students = (
    14 => [ 'Martha'   ],
    27 => [ 'Vivek'    ],
    31 => [ 'Era'      ],
    16 => [ 'Marty'    ],
    25 => [ 'Jason'    ],
    29 => [ 'Socrates' ],
    19 => [ 'Uri'      ],
    39 => [ 'Nitin', 'Plato' ],
); 

for my $key ( sort keys %students ) {
    for my $name ( @{$students{$key}} ) {
        print "$key => $name\n";
    }
}
Run Code Online (Sandbox Code Playgroud)

或者您甚至可以创建一个轻量级的“人”类。

use Z;

my $Person = class sub {
    has num  => ( type => PositiveInt );
    has name => ( type => NonEmptyStr );
};

my @students = (
    $Person->new( num => 14, name => 'Marta'    ),
    $Person->new( num => 27, name => 'Vivek'    ),
    $Person->new( num => 31, name => 'Era'      ),
    $Person->new( num => 16, name => 'Marty'    ),
    $Person->new( num => 25, name => 'Jason'    ),
    $Person->new( num => 29, name => 'Socrates' ),
    $Person->new( num => 19, name => 'Uri'      ),
    $Person->new( num => 39, name => 'Nitin'    ),
    $Person->new( num => 39, name => 'Plato'    ),
); 

for my $student ( @students ) {
    printf "%s => %s\n", $student->num, $student->name;
}
Run Code Online (Sandbox Code Playgroud)

有很多方法可以解决这个问题,但字符串的单个平面散列可能不是其中之一。