Perl中替换数据结构内所有配置文件键为标准键的简便方法
问题描述
我有一个包含哈希、数组的数据结构,涵盖环境、用户、配置文件、访问权限等内容,结构如下:
%AR = ( 'prod' => { 'username' => { 'access_profile1' => [ 'accessright1', 'accessright2', 'accessright3', 'accessrightN', ], 'access_profile2' => [ 'accessright7', 'accessright8', 'accessright9', ], 'access_profileN' => [ 'accessrightX', 'accessrightX', 'accessrightX', ], }, }, );
我想给脚本添加一个选项,启用该选项时将所有配置文件名称替换为标准名称(比如default_profile),重新生成结构(前提是所有访问权限唯一,否则会出现覆盖问题)。
我已经通过嵌套循环填充新数据结构的方式实现了需求,代码如下:
my $newAR; foreach my $env ( keys %AR ) { foreach my $user ( keys %{ $AR{$env} } ) { foreach my $profile ( keys %{ $AR{$env}{$user} } ) { # fill the new data structure foreach my $accessright (@{ $AR{$env}{$user}{$profile} }) { push (@{ $newAR{$env}{$user}{'default_profile'} }, $accessright); } } } }
最终可得到正确结果:
$VAR1 = { 'prod' => { 'username' => { 'default_profile' => [ 'accessrightX', 'accessrightX', 'accessrightX', 'accessright7', 'accessright8', 'accessright9', 'accessright1', 'accessright2', 'accessright3', 'accessrightN' ] } } };
但我对Perl的映射等特性不太熟悉,想了解是否存在更简洁的写法来替代这些嵌套循环?
简洁写法示例
1. 嵌套map实现结构转换
利用Perl的map函数替代多层循环,将转换逻辑压缩为更紧凑的声明式写法:
my $newAR = { map { my $env = $_; $env => { map { my $user = $_; $user => { default_profile => [ map { @{ $AR{$env}{$user}{$_} } } keys %{ $AR{$env}{$user} } ] } } keys %{ $AR{$env} } } } keys %AR };
三层嵌套的map分别遍历环境、用户、配置文件,直接将所有权限数组展开合并到default_profile对应的数组中,逻辑与原循环完全一致,但结构更紧凑。
2. 用values简化配置文件遍历
因为我们不需要用到配置文件的键名,仅需其对应的权限数组,可直接用values替代keys遍历,减少一层变量绑定:
my $newAR = { map { my $env = $_; $env => { map { my $user = $_; $user => { default_profile => [ map { @$_ } values %{ $AR{$env}{$user} } ] } } keys %{ $AR{$env} } } } keys %AR };
values %{ $AR{$env}{$user} }直接获取所有配置文件的权限数组,再通过map { @$_ }将每个数组展开,合并为一个大数组,代码更简洁。
3. 原地修改(无需保留原结构)
如果不需要保留原始%AR数据结构,可直接原地修改,省去创建新结构的开销:
foreach my $env (keys %AR) { foreach my $user (keys %{ $AR{$env} }) { # 合并所有权限数组 my @all_rights = map { @$_ } values %{ $AR{$env}{$user} }; # 替换原有的所有配置文件 %{ $AR{$env}{$user} } = ( default_profile => \@all_rights ); } }
这种写法去掉了最内层循环,直接用values和map合并所有权限,然后重写用户对应的哈希表,代码量更少。
内容的提问来源于stack exchange,提问作者olivierg
相关产品推荐
相关产品推荐

