Reputation: 5927
How can i reset the hash values in perl
use warnings;
use strict;
my %hash = qw(one 1 two 2 three 3 four 4);
my @key = keys(%hash);
my @avz = (9..12);
my %vzm;
print "Original hash and keys : ",%hash,"\n";
for(my $i = 0; $i<=scalar @avz; $i++){
my @new = "$key[$i] $avz[$i] ";
push(%vzm , @new);
}
print "modified hash and keys",%vzm,"\n";
I tried to alter the keys of original hash with another keys. How can i do it This program give the error is:
Original hash and keys : three3one1two2four4
Not an ARRAY reference at key.pl line 10.
I expect the output is
Original hash and keys : three3one1two2four4
modified hash and keys : three11one9two10four12
How can i do it
Upvotes: 0
Views: 111
Reputation: 53478
Ok, first off - you're doing something nasty in your code:
You're trying to take an ordered data structure - an array - and push it into a keyed data structure, which has no particular ordering defined.
This isn't going to work very well - it technically works, because internally perl treats arrays and hashes similarly.
But for example your first assignment - what you're actually getting is:
my %hash = (
one => 1,
two => 2,
three => 3,
four => 4
);
You can access the keys (in no particular order) via keys()
. And the values via values()
. But to try and treat it like an array is undefined behaviour.
To add elements to your array:
$hash{'nine'} = 9;
To delete elements from your array:
delete ( $hash{'one'} );
You can iterate on keys
or values
- and combined with sort
even do them in some sort of order. (Just bear in mind for sorting alphanumeric numbers you'll have a custom sort job).
foreach my $key ( sort keys %hash ) {
print "$key => $hash{$key}\n";
}
(Note - this is sorting by alphanumeric string, so gives:
four => 4
one => 1
three => 3
two => 2
If you want to sort by value:
foreach my $key ( sort { $hash{$a} <=> $hash{$b} } keys %hash ) {
print "$key => $hash{$key}\n";
}
And so you'll get:
one => 1
two => 2
three => 3
four => 4
So the real question remains - what are you actually trying to accomplish? The point of a hash is to give you an unordered mini-database of key-value pairs. Treating one like an array doesn't make an awful lot of sense. Either you're iterating hash elements in arbitrary order, or you're applying a specific sort to it - but one where you're relying on getting elements in a particular order is a bad plan - it may work, but it's not guaranteed to work, and that makes for bad code.
Upvotes: 2
Reputation: 50637
You have to keep the order of the keys in some array, or take it from original list
my @tmp = qw(one 1 two 2 three 3 four 4);
my %hash = @tmp;
# 'one', 'two', ..
my @key = @tmp[ grep !($_%2), 0 .. $#tmp ];
# ..
for my $i (0 .. $#avz) {
$vzm{ $key[$i] } = $avz[$i];
}
or using hash slice as more perlish approach,
@vzm{ @key } = @avz;
Upvotes: 1
Reputation: 780974
To create a hash element, you use assignment to $var{$key}
.
for (my $i = 0; $i < scalar @avz; $i++) {
$vzm{$key[$i]} = $avz[$i];
}
Note also that the loop condition should be <
, not <=
. List/array indexes end at scalar @avz - 1
.
Upvotes: 1
Reputation: 98398
You can't do what you want (replace the values for keys in the hash in the order they originally were added) without keeping track of that order separately, since the hash doesn't have any particular order. In other words, this:
my @key = keys(%hash);
needs to be this:
my @key = ( 'one', 'two', 'three', 'four' );
Once you have that, you can just assign the values all at once with a hash slice:
my %vzm;
@vzm{@key} = @avz;
Upvotes: 1