施瓦茨变换怎么样?
#! /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 变换。第一个 - 最接近结尾 - <code>map%data
以某种未指定的顺序展平或“反规范化”为记录列表。嵌套map
是到达子键所必需的。要处理任意深度的嵌套,请flatten
递归定义。
我们进行了较早的传递以收集所有使用的子键,因此如果不存在特定的子键,则值为$data{$key}{$_}
未定义的值。使用//
5.10.0 版中的定义或运算符 new 指定默认值""
.
带有扁平化的表格记录
[ "KEY1", "SUBKEY3", "75.00" ],
[ "KEY1", "SUBKEY1", "Canada" ],
...
排序很简单:比较各自的第一个元素(键),如果它们相等,则回退到秒(子键)。
最后,最外层map
格式化现在排序的非规范化记录以供输出,结果列表通过运算符进入标准输出print
。
输出:
KEY1:SUBKEY1 是“加拿大”
KEY1:SUBKEY2 是“50.00”
KEY1:SUBKEY3 是“75.00”
KEY2:SUBKEY1 是“墨西哥”
KEY2: SUBKEY2 是 ""
KEY2:SUBKEY3 是“200.00”
KEY3: SUBKEY1 是 ""
KEY3:SUBKEY2 是“150.00”
KEY3: SUBKEY3 是 ""
要将子键与每个子键的相应键分组在同一行,请使用以下代码
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";
}
你可以用函数式的风格来写它,但结果是一团糟:
print map { my $key = $_;
"$key: " .
join(", " =>
map { my $value = $data{$key}{$_} // "";
qq|$_ is "$value"|
}
@subkeys) .
"\n"
}
sort keys %data;
输出:
KEY1:SUBKEY1 为“加拿大”,SUBKEY2 为“50.00”,SUBKEY3 为“75.00”
KEY2:SUBKEY1 是“墨西哥”,SUBKEY2 是“”,SUBKEY3 是“200.00”
KEY3:SUBKEY1为“”,SUBKEY2为“150.00”,SUBKEY3为“”