Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can anyone explain how to print all keys if two keys are same but with different values?

Tags:

string

hash

perl

In this code two keys "39" are same name but different values , I want to print both keys

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};
} 

I am getting error.

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.

Expected Output

14   Martha
27   Vivek 
31   Era
16   Marty 
25   Jason 
29   Socrates 
19   Uri
39   Nitin 
39   Plato

Can anyone tell me how to do it?

like image 727
Alexx Avatar asked Sep 30 '20 11:09

Alexx


People also ask

Can we have two same keys with different values?

You can't. Keys have to be unique.

Can a dictionary have two key value pairs with the same value but different keys?

Answer. No, each key in a dictionary should be unique. You can't have two keys with the same value.

How do you check if keys in a dictionary have the same value Python?

Check if a key-value pair exists in a dictionary: in operator, items() To check if a key-value pair exists in a dictionary, i.e., if a dictionary has/contains a pair, use the in operator and the items() method. Specify a tuple (key, value) . Use not in to check if a pair does not exist in a dictionary.

Does dictionary accept duplicate keys?

[C#] Dictionary with duplicate keysThe Key value of a Dictionary is unique and doesn't let you add a duplicate key entry. To accomplish the need of duplicates keys, i used a List of type KeyValuePair<> .


3 Answers

Two keys cannot be the same. One will overwrite the other. If you want to have multiple values for one key then you need to design your data structure to support that (e.g. by having the value be an arrayref).

Your error messages are unrelated to that problem (you forgot to put quotes around your string values).

like image 144
Quentin Avatar answered Oct 16 '22 18:10

Quentin


This is kinda close:

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";
}

But really you want to use a different data structure. Perhaps an array of 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";
}

Or an array of 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";
}

Or a hash of 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";
    }
}

Or you could even create a lightweight "person" class.

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;
}

There's a lot of ways to go about solving this, but a single flat hash of strings is probably not one of them.

like image 32
tobyink Avatar answered Oct 16 '22 18:10

tobyink


As a starter: the hash values are strings, so they need to be quoted. This is why you are getting a syntax error:

my %studentnames = ( 
    14 => 'Martha', 
    27 => 'Vivek', 
    31 => 'Era', 
    ... 
); 

Then: there is a misconception of what a Perl hash is. Each key in the hash must be unique. Perl tolerates declaring a hash with duplicate keys, but under the hood, only the last value of each key is retained.

So this:

my %studentnames = ( 
    14 => 'Martha', 
    39 => 'Nitin', 
    39 => 'Plato' 
); 

Is equivalent to:

my %studentnames = ( 
    14 => 'Martha', 
    39 => 'Plato' 
); 

Another way to see it is to put the assignments in separate instructions:

my %studentnames;
$studentnames{14} = 'Martha';
$studentnames{39} = 'Nitin';
$studentnames{39} = 'Plato';

print $studentnames{39}, "\n";
# Plato
like image 4
GMB Avatar answered Oct 16 '22 18:10

GMB