繁体   English   中英

将Perl哈希合并为一个数组并循环遍历

[英]Merge Perl hashes into one array and loop through it

我正在为cPanel创建一个Perl插件,该插件必须获取用户帐户中的所有域并将其显示在HTML select字段中。 最初,我是PHP开发人员,所以我很难理解Perl的某些逻辑。 我确实知道cPanel插件也可以用PHP编写,但是对于该插件,我仅限于Perl。

这就是我从cPanel获取数据的方式:

my @user_domains = $cpliveapi->uapi('DomainInfo', 'list_domains');
@user_domains = $user_domains[0]{cpanelresult}{result}{data};

这是使用print Dumper @user_domains

$VAR1 = {
    'addon_domains' => ['domain1.com', 'domain2.com', 'domain3.com'],
    'parked_domains' => ['parked1.com', 'parked2.com', 'parked3.com'],
    'main_domain' => 'main-domain.com',
    'sub_domains' => ['sub1.main-domain.com', 'sub2.main-domain.com']
};

我希望数据看起来像这样(感谢@simbabque):

@domains = qw(domain1.com domain2.com domain3.com main-domain.com parked1.com parked2.com parked3.com);

因此,我想排除sub_domains并将其他合并到一个一维数组中,这样我就可以通过一个循环遍历它们。 在过去的几天里,我一直在努力完成一项听起来非常简单的任务,但是我无法解决这个问题。

那不是在做你想做的事。 {}是匿名哈希构造函数,因此您要创建一个1元素数组,其中包含一个哈希。

您可能想要:

use Data::Dumper;

my %user_domains = (
    'addon_domains' => ['domain1.com', 'domain2.com', 'domain3.com'],
    'parked_domains' => ['parked1.com', 'parked2.com', 'parked3.com'],
    'main_domain' => 'main-domain.com',
    'sub_domains' => ['sub1.main-domain.com', 'sub2.main-domain.com'],
);

print Dumper \%user_domains;

然后可以通过双循环迭代“其他”数组元素:

foreach my $key ( keys %user_domains ) { 
    if ( not ref $user_domains{$key} ) { 
        print $user_domains{$key},"\n";
        next;
    }
    foreach my $domain (  @{$user_domains{$key}} ) {
        print $domain,"\n";
    }
}

或者,如果您真的想“整理”您的哈希:

my @flatten = map { ref $_ : @$_ ? $_ } values %user_domains;
print Dumper \@flatten;

(您需要ref测试,因为如果没有它,非数组main-domain将无法正常工作)

因此,为了保持一致性,您可能会拥有更好的选择:

my %user_domains = (
    'addon_domains' => ['domain1.com', 'domain2.com', 'domain3.com'],
    'parked_domains' => ['parked1.com', 'parked2.com', 'parked3.com'],
    'main_domain' => ['main-domain.com'],
    'sub_domains' => ['sub1.main-domain.com', 'sub2.main-domain.com'],
);

你需要这样的东西

如果您发现有List::Util的副本,其中不包含uniq则可以升级模块或使用此定义

sub uniq {
    my %seen;
    grep { not $seen{$_}++ } @_;
}

从您的转储中, uapi调用返回对hash引用 进入$cp_response ,然后深入到结构中,将data哈希引用提取到$data

delete从哈希中删除子域信息。

您想要的列表是$data引用的哈希 ,因此我将其提取出来。 如果列表中有多个域,则这些值是字符串数组引用 ;如果只有一个域,则是简单字符串

map通过取消引用数组引用或直接传递字符串将所有域名转换为单个列表。 那就是ref() ? @$_ : $_ ref() ? @$_ : $_正在执行。 最后, uniq删除多次出现的相同名称

use List::Util 'uniq';

my $cp_response = $cpliveapi->uapi('DomainInfo', 'list_domains');
my $data        = $cp_response->{cpanelresult}{result}{data};

delete $data->{sub_domains};

my @domains = uniq map { ref() ? @$_ : $_ } values %$data;

输出

parked1.com
parked2.com
parked3.com
domain1.com
domain2.com
domain3.com
main-domain.com

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM