my %data (
KEY1 => {
SUBKEY1 => "Canada",
SUBKEY3 => "75.00",
SUBKEY2 => "50.00",
},
KEY3 => {
SUBKEY2 => "150.00",
},
KEY2 => {
SUBKEY3 => "200.00",
SUBKEY1 => "Mexico",
},
);
如何打印按Keyname排序的列表以及按子角色排序的每个键名?
这是我要打印的内容: (请注意,如果未定义子项,则存在具有空字符串的子键的占位符)
KEY1: SUBKEY1 is "Canada"
KEY1: SUBKEY2 is "50.00"
KEY1: SUBKEY3 is "75.00"
KEY2: SUBKEY1 is ''
KEY2: SUBKEY2 is "150.00"
KEY2: SUBKEY3 is ''
KEY3: SUBKEY1 is "Mexico"
KEY3: SUBKEY2 is ''
KEY3: SUBKEY3 is "200.00"
答案 0 :(得分:3)
use strict;
use warnings;
my %data = (
KEY1 => {
SUBKEY1 => "Canada",
SUBKEY3 => "75.00",
SUBKEY2 => "50.00",
},
KEY3 => {
SUBKEY2 => "150.00",
},
KEY2 => {
SUBKEY3 => "200.00",
SUBKEY1 => "Mexico",
},
);
my %all_sub_keys;
for my $sub_hash (values %data){
$all_sub_keys{$_} ++ for keys %$sub_hash;
}
my @all_sub_keys = sort keys %all_sub_keys;
for my $k ( sort keys %data ){
for my $sk (@all_sub_keys){
my $val = exists $data{$k}{$sk} ? $data{$k}{$sk} : '--';
print join(' ', $k, $sk, $val), "\n";
}
}
答案 1 :(得分:3)
#! /usr/bin/perl
use 5.10.0; # for // (aka defined-or)
use warnings;
use strict;
my %data = ...;
# get all subkeys used in %data
my @subkeys = keys %{
{ map { map +($_ => 1),
keys %{ $data{$_} } }
keys %data
}
};
print map qq|$_->[0]: $_->[1] is "$_->[2]"\n|,
sort { $a->[0] cmp $b->[0]
||
$a->[1] cmp $b->[1] }
map { my $key = $_;
map [ $key, $_, $data{$key}{$_} // "" ] =>
@subkeys }
keys %data;
请记住从后到前阅读Schwartzian变换。第一个最接近结尾 - map
将某个未指定顺序的记录列表展平或“非规范化”%data
。嵌套map
是到达子键所必需的。要处理任意深度嵌套,请递归定义{{1}}。
我们做了一个早期的传递来收集所有使用的子密钥,因此如果没有特定的子密钥,flatten
的值是未定义的值。使用$data{$key}{$_}
,版本5.10.0中的defined-or new new指定默认值//
。
使用格式的记录
""
排序很简单:比较各自的第一个元素(键),如果它们相等,则回退到秒(子键)。
最后,最外面的[ "KEY1", "SUBKEY3", "75.00" ],
[ "KEY1", "SUBKEY1", "Canada" ],
...
格式化现在排序的非规范化记录以进行输出,结果列表通过map
运算符转到标准输出。
输出:
KEY1: SUBKEY1 is "Canada" KEY1: SUBKEY2 is "50.00" KEY1: SUBKEY3 is "75.00" KEY2: SUBKEY1 is "Mexico" KEY2: SUBKEY2 is "" KEY2: SUBKEY3 is "200.00" KEY3: SUBKEY1 is "" KEY3: SUBKEY2 is "150.00" KEY3: SUBKEY3 is ""
要使用每个键的相应键将同一行的子键分组,请使用
等代码print
你可以用功能风格来编写它,但结果却是一团糟:
my @subkeys = sort keys %{ ... ;
foreach my $key (sort keys %data) {
my @values;
foreach my $subkey (@subkeys) {
my $value = $data{$key}{$subkey} // "";
push @values => qq|$subkey is "$value"|;
}
local $" = ", ";
print "$key: @values\n";
}
输出:
KEY1: SUBKEY1 is "Canada", SUBKEY2 is "50.00", SUBKEY3 is "75.00" KEY2: SUBKEY1 is "Mexico", SUBKEY2 is "", SUBKEY3 is "200.00" KEY3: SUBKEY1 is "", SUBKEY2 is "150.00", SUBKEY3 is ""
答案 2 :(得分:2)
我假设提前知道了一组子项。
#!/usr/bin/perl
use strict; use warnings;
my %data = (
KEY1 => {
SUBKEY1 => "Canada",
SUBKEY3 => "75.00",
SUBKEY2 => "50.00",
},
KEY3 => {
SUBKEY2 => "150.00",
},
KEY2 => {
SUBKEY3 => "200.00",
SUBKEY1 => "Mexico",
},
);
my @subkeys = qw( SUBKEY1 SUBKEY2 SUBKEY3 );
for my $key ( sort keys %data ) {
my %sub = map {
my $v = $data{$key}{$_};
$_ => defined($v) ? $v : '';
} @subkeys;
for my $subkey ( @subkeys ) {
print "$key $subkey $sub{$subkey}\n";
}
}
输出:
KEY1 SUBKEY1 Canada KEY1 SUBKEY2 50.00 KEY1 SUBKEY3 75.00 KEY2 SUBKEY1 Mexico KEY2 SUBKEY2 KEY2 SUBKEY3 200.00 KEY3 SUBKEY1 KEY3 SUBKEY2 150.00 KEY3 SUBKEY3