i was wondering if there was a easy way to convert a complete data strucure (mix of HoH/Arrays) to Uppercase ?
e.g., i have a structure containing many entries like this :
'oracle' => {
'sit' => {
'ZQ01-42P-PBTOKEN' => [
'ora:morningcheck',
'ora:simpana_bkp',
'ora:oraclepatching'
]
},
'prd' => {
'ZQ01-42P-PBTOKEN' => [
'ora:morningcheck',
'ora:simpana_bkp',
'odg:oraclepatching',
'ora:oraclepatching'
]
},
'uat' => {
'ZQ01-42P-PBTOKEN' => [
'ora:morningcheck',
'ora:simpana_bkp',
'odg:oraclepatching',
'ora:oraclepatching'
]
},
'PRD' => {
'ZQ01-42P-UXGROUP' => [
'socdbaud',
'oramgrp',
'wmioca',
'oramigration',
'tac'
]
and i want everthing (both keys & values) in uc() is there a neat way to do it ?
i tried this but it fails (afterwards i get : 'ORACLE' => 'HASH(0X2941738)')
%ds = map uc, %ds;
thanks for any tips!
CodePudding user response:
You can use a recursive function that does the Right Thing (tm) depending on the type of its argument:
#!/usr/bin/env perl
use warnings;
use strict;
use experimental qw/signatures/;
use Scalar::Util qw/blessed reftype/;
use Data::Dumper;
sub to_upper($var) {
die "Blessed objects aren't supported" if blessed $var;
my $type = reftype $var;
if (!defined $type) {
return uc $var;
} elsif ($type eq "ARRAY") {
return [ map { to_upper($_) } @$var ]
} elsif ($type eq "HASH") {
my %uchash;
while (my ($key, $val) = each %$var) {
$uchash{uc $key} = to_upper($val);
}
return \%uchash;
} elsif ($type eq "SCALAR") {
my $uc = uc $$var;
return \$uc;
} else {
die "Unsupported reference type $type";
}
}
my $var = {
'oracle' => {
'sit' => {
'ZQ01-42P-PBTOKEN' => [
'ora:morningcheck',
'ora:simpana_bkp',
'ora:oraclepatching'
]
},
'prd' => {
'ZQ01-42P-PBTOKEN' => [
'ora:morningcheck',
'ora:simpana_bkp',
'odg:oraclepatching',
'ora:oraclepatching'
]
},
'uat' => {
'ZQ01-42P-PBTOKEN' => [
'ora:morningcheck',
'ora:simpana_bkp',
'odg:oraclepatching',
'ora:oraclepatching'
]
},
'PRD' => {
'ZQ01-42P-UXGROUP' => [
'socdbaud',
'oramgrp',
'wmioca',
'oramigration',
'tac'
]
}
}
};
my $ucvar = to_upper $var;
print Dumper($ucvar);
prints out
$VAR1 = {
'ORACLE' => {
'PRD' => {
'ZQ01-42P-PBTOKEN' => [
'ORA:MORNINGCHECK',
'ORA:SIMPANA_BKP',
'ODG:ORACLEPATCHING',
'ORA:ORACLEPATCHING'
]
},
'UAT' => {
'ZQ01-42P-PBTOKEN' => [
'ORA:MORNINGCHECK',
'ORA:SIMPANA_BKP',
'ODG:ORACLEPATCHING',
'ORA:ORACLEPATCHING'
]
},
'SIT' => {
'ZQ01-42P-PBTOKEN' => [
'ORA:MORNINGCHECK',
'ORA:SIMPANA_BKP',
'ORA:ORACLEPATCHING'
]
}
}
};
(Upper casing the keys of your hash results in duplicates and only one of them is kept)
CodePudding user response:
The desired conversation can be achieved with a simple conversion of data structure to JSON string, converting JSON string to upper case and then convert the string back to data structure.
use strict;
use warnings;
use JSON;
use Data::Dumper;
my($var,$data);
$var = {
'oracle' => {
'sit' => {
'ZQ01-42P-PBTOKEN' => [
'ora:morningcheck',
'ora:simpana_bkp',
'ora:oraclepatching'
]
},
'prd' => {
'ZQ01-42P-PBTOKEN' => [
'ora:morningcheck',
'ora:simpana_bkp',
'odg:oraclepatching',
'ora:oraclepatching'
]
},
'uat' => {
'ZQ01-42P-PBTOKEN' => [
'ora:morningcheck',
'ora:simpana_bkp',
'odg:oraclepatching',
'ora:oraclepatching'
]
},
'PRD' => {
'ZQ01-42P-UXGROUP' => [
'socdbaud',
'oramgrp',
'wmioca',
'oramigration',
'tac'
]
}
}
};
$data = uc to_json($var);
$data = from_json($data);
print Dumper($data);
Output
$VAR1 = {
'ORACLE' => {
'SIT' => {
'ZQ01-42P-PBTOKEN' => [
'ORA:MORNINGCHECK',
'ORA:SIMPANA_BKP',
'ORA:ORACLEPATCHING'
]
},
'PRD' => {
'ZQ01-42P-PBTOKEN' => [
'ORA:MORNINGCHECK',
'ORA:SIMPANA_BKP',
'ODG:ORACLEPATCHING',
'ORA:ORACLEPATCHING'
]
},
'UAT' => {
'ZQ01-42P-PBTOKEN' => [
'ORA:MORNINGCHECK',
'ORA:SIMPANA_BKP',
'ODG:ORACLEPATCHING',
'ORA:ORACLEPATCHING'
]
}
}
};