use Data::Dumper;
%hash = (
Key => {test => [[testvalue, 10], [testvalue, 20]]},
Key2 => {test => [[testvalue, 30], [testvalue, 40]]},
);
my $parm = $hash{Key}{test};
foreach my $test_p (#{$parm}) {
print Dumper $test_p;
}
It is not displaying in the way I expect.
A comma is missing at the end of the first line.
%hash = (
Key => {
test => [
[ testvalue , 10 ],
[ testvalue , 20 ]
]
},
Key2 => {
test => [
[ testvalue , 30 ],
[ testvalue , 40 ]
]
}
);
my $parm = $hash{Key}{test} ;
foreach my $test_p (#$parm) {
use Data::Dumper;
print Dumper $test_p;
}
You can try this:
my %hash = (
Key => {test => [['testvalue', 10], ['testvalue', 20]]},
Key2 => {test => [['testvalue', 30], ['testvalue', 40]]},
);
my $parm = $hash{Key}{test};
foreach my $test_p (#{$parm}) {
print Dumper $test_p;
}
foreach my $test (keys %hash) {
my $test1 = $hash{$test};
print Dumper $test;
foreach my $test2 (keys %{$test1}) {
print Dumper $test2;
my $test3 = $hash{$test}{$test2};
foreach my $test_p (#{$test3}) {
print Dumper #{$test_p};
}
}
}
Perhaps:
#/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
sub main{
my %hash = ( Key => { test => [[ "testvalue" , 10 ], [ "testvalue" ,20]] },
Key2 => { test => [[ "testvalue" , 30 ], [ "testvalue" ,40]] } );
foreach my $key (sort keys %hash){
my $parm = $hash{$key}{test};
print Dumper $_ foreach(#$parm);
}
}
main();
Outputs:
$VAR1 = [
'testvalue',
10
];
$VAR1 = [
'testvalue',
20
];
$VAR1 = [
'testvalue',
30
];
$VAR1 = [
'testvalue',
40
];
Related
I am trying to find the key name as output by matching $country_value variable in grep through the hash I have.
#!/usr/bin/perl -w
use strict;
use warnings;
my $country_value = 1;
my $country = {
'IN' => [
1,
5
],
'US' => [
2,
6
],
'UK' => [
3,
7
]
};
my $country_details = grep { $_ eq $country_value } values %{$country};
print $country_details;
print "\n";
As per the hash, I need to get the output as IN because the value of IN is 1 and the $country_value is 1, which is what I am trying to find out.
But, I get the output as 0 instead of IN.
Can someone please help?
In your code, values returns a reference to an array. You need to dereference that to get a list for grep.
use warnings;
use strict;
my $country_value = 1;
my $country = {
'IN' => [
1,
5
],
'US' => [
2,
6
],
'UK' => [
3,
7
]
};
my $country_details;
for my $name (keys %{$country}) {
if (grep { $_ == $country_value } #{ $country->{$name} }) {
$country_details = $name;
last;
}
}
print $country_details, "\n";
Prints:
IN
Have this code:
use 5.020;
use warnings;
use Data::Dumper;
my %h = (
k1 => [qw(aa1 aa2 aa1)],
k2 => [qw(ab1 ab2 ab3)],
k3 => [qw(ac1 ac1 ac1)],
);
my %h2;
for my $k (keys %h) {
$h2{$k}{$_}++ for (#{$h{$k}});
}
say Dumper \%h2;
produces:
$VAR1 = {
'k1' => {
'aa2' => 1,
'aa1' => 2
},
'k3' => {
'ac1' => 3
},
'k2' => {
'ab1' => 1,
'ab3' => 1,
'ab2' => 1
}
};
Is possible to write the above code with "another way"? (e.g. simpler or more compact)?
Honestly, I don't like the number of times $h2{$k} is evaluated.
my %h2;
for my $k (keys %h) {
my $src = $h{$k};
my $dst = $h2{$k} = {};
++$dst->{$_} for #$src;
}
A subroutine can help make the intent more obvious. Maybe.
sub counts { my %c; ++$c{$_} for #_; \%c }
$h2{$_} = counts(#{ $h{$_} }) for keys %h;
That can be simplified if you do the change in-place.
sub counts { my %c; ++$c{$_} for #_; \%c }
$_ = counts(#$_) for values %h;
data :
%HoH => (
abc => {
value => "12",
},
xyz => {
number => "100",
},
pqr => {
digit => "5",
}
)
How do I sort the hash of hash by value in descending order?
Output
100
12
5
You can't sort a hash, it won't hold the order. If you wanted to keep them sorted, you'll have to sort the keys based on the number and store the keys in an array.
#!/usr/bin/perl
use strict;
use warnings;
my %HoH = (
abc => { value => 12 },
xyz => { value => 100},
pqr => { value => 5},
def => { value => 15},
hij => { value => 30},
);
my #sorted_keys = map { $_->[0] }
sort { $b->[1] <=> $a->[1] } # use numeric comparison
map { my $temp;
if ( exists $HoH{$_}{'value'} ) {
$temp = $HoH{$_}{'value'};
} elsif ( exists $HoH{$_}{'number'} ) {
$temp = $HoH{$_}{'number'};
} elsif ( exists $HoH{$_}{'digit'} ) {
$temp = $HoH{$_}{'digit'};
} else {
$temp = 0;
}
{[$_, $temp]} }
(keys %HoH);
for my $key (#sorted_keys) {
my $temp;
if ( exists $HoH{$key}{'value'} ) {
$temp = $HoH{$key}{'value'};
} elsif ( exists $HoH{$key}{'number'} ) {
$temp = $HoH{$key}{'number'};
} elsif ( exists $HoH{$key}{'digit'} ) {
$temp = $HoH{$key}{'digit'};
} else {
$temp = 0;
}
print $key . ":" . $temp ."\n";
}
Output:
xyz:100
hij:30
def:15
abc:12
pqr:5
This technique to do the sorting is called Schwartzian Transform.
Given you're not actually using the keys for anything, you can flatten the data structure into a single array and then sort it:
use strict;
use warnings;
my %HoH = (
abc => {value => "12",},
xyz => {number => "100",},
pqr => {digit => "5",},
);
my #numbers = sort {$b <=> $a} map {values %$_} values %HoH;
print "$_\n" for #numbers;
Outputs:
100
12
5
However, if you want to use the additional key information, then you'll need fold your Hash of Hash into an array, and then you can sort however you like:
my #array;
while (my ($k, $ref) = each %HoH) {
while (my ($k2, $v) = each %$ref) {
push #array, [$k, $k2, $v];
}
}
#array = sort {$b->[2] <=> $a->[2]} #array;
use Data::Dump;
dd \#array;
Outputs:
[
["xyz", "number", 100],
["abc", "value", 12],
["pqr", "digit", 5],
]
I came up with this solution
#!/usr/bin/perl
use strict;
use warnings;
my %HoH = (
abc => {
value => "12",
},
xyz => {
number => "100",
},
pqr => {
digit => "5",
}
);
my %rever;
for my $TopKey(keys %HoH){
for my $value(values %{ $HoH{$TopKey} }){
push #{ $rever{$value} }, $TopKey;
}
}
my #nums = sort {$b <=> $a} (keys(%rever));
print $_, "\n" for #nums;
I reversed the values in case you still needed to use the key names.
This is how it looks after using Dumper.
$VAR1 = '100';
$VAR2 = [
'xyz'
];
$VAR3 = '12';
$VAR4 = [
'abc'
];
$VAR5 = '5';
$VAR6 = [
'pqr'
];
I would expect the following code
my #array;
for my $rapport ( qw( value1 value2 value3 ) ) {
push #array, { key => $rapport };
}
to produce:
$VAR1 = [
{
'key' => 'value1'
},
{
'key' => 'value2'
},
{
'key' => 'value3'
}
];
However, running this code segment under Catalyst MVC I get:
$VAR1 = [
{
'key' => [ 'value', 'value2', 'value3' ]
},
];
Can someone please explain to me why?
EDIT: could anyone with the same issue please add an example? I cannot reproduce after some code changes, but as it has been upvoted 5 times I assume some other users have also experienced this issue?
This code example...
#!/usr/bin/perl
use Data::Dumper;
my #input = ( "var1", "var2", "var3" );
my #array;
for my $rapport ( #input ) {
push #array, { key => $rapport };
}
print Dumper( \#array );
exit;
produces ...
$VAR1 = [
{
'key' => 'var1'
},
{
'key' => 'var2'
},
{
'key' => 'var3'
}
];
But the following...
#!/usr/bin/perl
use Data::Dumper;
my #input = [ "var1", "var2", "var3" ]; # sometimes people forget to dereference their variables
my #array;
for my $rapport ( #input ) {
push #array, { key => $rapport };
}
print Dumper( \#array );
exit;
shows...
$VAR1 = [
{
'key' => [
'var1',
'var2',
'var3'
]
}
];
As you can see both examples loop through an array but the second one is an array, that was initialized with a reference value. Since in Catalyst you normally ship various values through your application via stash or similar constructs, you could check weather your array really contains scalar values : )
I have this code
use strict;
use warnings;
my %hash;
$hash{'1'}= {'Make' => 'Toyota','Color' => 'Red',};
$hash{'2'}= {'Make' => 'Ford','Color' => 'Blue',};
$hash{'3'}= {'Make' => 'Honda','Color' => 'Yellow',};
foreach my $key (keys %hash){
my $a = $hash{$key}{'Make'};
my $b = $hash{$key}{'Color'};
print "$a $b\n";
}
And this out put:
Toyota Red Honda Yellow Ford Blue
Need help sorting it by Make.
#!/usr/bin/perl
use strict;
use warnings;
my %hash = (
1 => { Make => 'Toyota', Color => 'Red', },
2 => { Make => 'Ford', Color => 'Blue', },
3 => { Make => 'Honda', Color => 'Yellow', },
);
# if you still need the keys...
foreach my $key ( #
sort { $hash{$a}->{Make} cmp $hash{$b}->{Make} } #
keys %hash
)
{
my $value = $hash{$key};
printf( "%s %s\n", $value->{Make}, $value->{Color} );
}
# if you don't...
foreach my $value ( #
sort { $a->{Make} cmp $b->{Make} } #
values %hash
)
{
printf( "%s %s\n", $value->{Make}, $value->{Color} );
}
print "$_->{Make} $_->{Color}" for
sort {
$b->{Make} cmp $a->{Make}
} values %hash;
plusplus is right... an array of hashrefs is likely a better choice of data structure. It's more scalable too; add more cars with push:
my #cars = (
{ make => 'Toyota', Color => 'Red' },
{ make => 'Ford' , Color => 'Blue' },
{ make => 'Honda' , Color => 'Yellow' },
);
foreach my $car ( sort { $a->{make} cmp $b->{make} } #cars ) {
foreach my $attribute ( keys %{ $car } ) {
print $attribute, ' : ', $car->{$attribute}, "\n";
}
}