我有一个数组和哈希的哈希,如下所示:
$VAR1 = \{
'abc' => {
'def' => 'WorkSet',
'products' => [
{
'prodtype' => 'Dell',
'product' => 'Powerconnect-5600'
},
{
'prodtype' => 'Dell',
'product' => 'R-720'
},
{
'prodtype' => 'Dell',
'product' => 'R-920'
}
]
},
'123' => {
'456' => 'WorkSet',
'products' => [
{
'prodtype' => 'Dell',
'product' => '210'
},
{
'prodtype' => 'Dell',
'product' => 'TZ-200'
},
{
'prodtype' => 'Dell',
'product' => 'TZ-200'
},
]
}
}
我想有这样的:
Branch: Workset
Build Number: abc
product : Dell producttype : PowerConnect-5600
product : Dell producttypr : R-720
product : Dell producttype : R-920
哈希值123也应该相同。
我知道单独使用上面的哈希,但发现很难在循环中进行。
请给我你的指导。
仅供参考,我已使用Data:Dumper perl模块列出了上述哈希值。
This is what I thought and tried but not getting the required answer in loops:
my @unique = uniq @version;
foreach $version(@ unique){
my $i=0;
print "$list->{$version}{branch}\n";
print "$list->{$version}->{products}->[$i]->{product}\n";
$i=$i+1;
} where @unique = qw (abc,123)
答案 0 :(得分:1)
这将取消引用您的结构(前提是每个构建号只有2个元素 - 分支和数组或产品)。您将'产品'作为'prodtype'(例如prodtype => Dell
),在您的哈希中,'prodtype'作为'产品' - 与名称相反。您应该考虑按照Jason Gray的建议改进数据结构。
#!/usr/bin/perl
use strict;
use warnings;
my $hash = {
'abc' => {
'def' => 'WorkSet',
'products' => [
{
'prodtype' => 'Dell',
'product' => 'Powerconnect-5600'
},
{
'prodtype' => 'Dell',
'product' => 'R-720'
},
{
'prodtype' => 'Dell',
'product' => 'R-920'
}
]
},
'123' => {
'456' => 'WorkSet',
'products' => [
{
'prodtype' => 'Dell',
'product' => '210'
},
{
'prodtype' => 'Dell',
'product' => 'TZ-200'
},
{
'prodtype' => 'Dell',
'product' => 'TZ-200'
},
]
}
};
while (my ($build_num, $href) = each %$hash) {
my ($branch, $aref);
for my $key (keys %$href) {
if (ref($href->{$key}) eq 'ARRAY') {
$aref = $href->{$key};
}
else {
$branch = $href->{$key};
}
}
print "Branch: $branch\n";
print "Build Number: $build_num\n";
for my $href (@$aref) {
print "product: $href->{prodtype} prodtype: $href->{product}\n";
}
print "\n";
}
将输出打印为:
Branch: WorkSet
Build Number: 123
product: Dell prodtype: 210
product: Dell prodtype: TZ-200
product: Dell prodtype: TZ-200
Branch: WorkSet
Build Number: abc
product: Dell prodtype: Powerconnect-5600
product: Dell prodtype: R-720
product: Dell prodtype: R-920
答案 1 :(得分:1)
但是,我意识到这不完全是您的数据结构。我提供了一个你可以稍微采用不同方法的方法的例子。
use strict;
use warnings;
use feature 'say';
my $h = {
abc => {
Workset => {
Dell => [
'Powerconnect-5600',
'R-270',
'R-920',
],
},
},
123 => {
Workset => {
Dell => [
'210',
'TZ-200',
],
},
},
};
for my $k ( keys %$h ) {
for my $j ( keys %$h->{$k} ) {
for my $prod ( keys %$h->{$k}{$j} ) {
say "Branch: $j";
say "Build Number: $k";
say "product : $prod producttype : " . $_ for @{ $h->{$k}{$j}{$prod} };
}
}
}
输出:
Branch: Workset
Build Number: 123
product : Dell producttype : 210
product : Dell producttype : TZ-200
Branch: Workset
Build Number: abc
product : Dell producttype : Powerconnect-5600
product : Dell producttype : R-270
product : Dell producttype : R-920
答案 2 :(得分:1)
问题已经得到解答和接受,但无论如何我必须打开我的陷阱......
首先,我认为你的结构是关闭的。它应该是这样的:
$VAR1 = {
'123' => bless( {
'ARRAY' => [
bless( {
'PRODUCT' => 'Dell',
'TYPE' => '210'
}, 'Product' ),
bless( {
'PRODUCT' => 'Dell',
'TYPE' => 'TZ-200'
}, 'Product' ),
bless( {
'PRODUCT' => 'Dell',
'TYPE' => 'TZ-200'
}, 'Product' )
]
}, 'Build' ),
'abc' => bless( {
'ARRAY' => [
bless( {
'PRODUCT' => 'Dell',
'TYPE' => 'Powerconnect-5600'
}, 'Product' ),
bless( {
'PRODUCT' => 'Dell',
'TYPE' => 'R-720'
}, 'Product' ),
bless( {
'PRODUCT' => 'Dell',
'TYPE' => 'R-920'
}, 'Product' )
]
}, 'Build' )
};
我基于你想要的输出。看起来你有 Builds ,它包含一系列产品。产品包含产品类型和产品描述。在您的原始结构中,您有:
`456` => Workset`
但结构的这一部分毫无意义,你不使用它。也许你的意思是分支类型?很难说。让其他一切我都不理解,我忽略了它。
现在,你应该如何解析这个结构?您应该使用Perl Object Oriented Programming。这使您可以不再担心数据结构。你的课程定义将负责这一点。如果这是散列数组,散列或数组,或者数组或数组的哈希值,您不必担心。
这是整个主程序。两个循环:在第一个循环中,我读入数据(由三个制表符分隔的项目组成:构建号,产品类型和产品)。它清晰,简洁,易于理解。只需要六行代码就可以解析整个数据结构:
use strict;
use warnings;
use feature qw(say);
my %workset;
my $prev_build;
#
# Read in the Data
#
while ( my $line = <DATA> ) {
chomp $line;
my ($build_num, $prodtype, $description) = split /\t/, $line;
my $product = Product->new( $prodtype, $description );
if ( not $prev_build or $prev_build ne $build_num ) {
$workset{$build_num} = Build->new;
$prev_build = $build_num;
}
$workset{$build_num}->Push($product);
}
#
# Parse the structure and Print it out
#
for my $workset ( sort keys %workset ) {
say "Build Number: " . $workset;
while ( my $product = $workset{$workset}->Pop ) {
say "Product: " . $product->Product . " Prodtype: " . $product->Type;
}
}
这是输出:
Build Number: 123
Product: Dell Prodtype: TZ-200
Product: Dell Prodtype: TZ-200
Product: Dell Prodtype: 210
Build Number: abc
Product: Dell Prodtype: R-920
Product: Dell Prodtype: R-720
Product: Dell Prodtype: Powerconnect-5600
就像你想要的那样。
我的程序的其余部分是类定义。大多数时候,我只是将定义附加到主程序的末尾,因为我再也没有使用它们。尽管如此,使用面向对象的代码使编程变得更快更容易。
这是我程序的其余部分:
package Product;
sub new {
my $class = shift;
my $product = shift;
my $type = shift;
my $self = {};
bless $self, $class;
$self->Product($product);
$self->Type($type);
return $self;
}
sub Product {
my $self = shift;
my $product = shift;
if ( defined $product ) {
$self->{PRODUCT} = $product;
}
return $self->{PRODUCT};
}
sub Type {
my $self = shift;
my $type = shift;
if ( defined $type ) {
$self->{TYPE} = $type;
}
return $self->{TYPE};
}
package Build;
use Carp;
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
return $self;
}
# PRIVATE -- No peeking
sub _Array_ref {
my $self = shift;
if ( not exists $self->{ARRAY} ) {
$self->{ARRAY} = [];
}
return $self->{ARRAY};
}
sub Index {
my $self = shift;
my $index = shift;
if ( not defined $self->{INDEX} ) {
$self->{INDEX} = 0;
}
if ( defined $index ) {
$self->{INDEX} = $index;
}
if ( $self->{INDEX} < 0 or $self->{INDEX} > $self->Size ) {
croak qq(Index out of range: Set to "$index");
}
return $self->{INDEX};
}
sub Array {
my $self = shift;
my @array = @{ $self->_Array_ref };
return wantarray ? @array : \@array;
}
sub Size {
my $self = shift;
my $array_ref = $self->_Array_ref;
return $#{ $array_ref };
}
sub Push {
my $self = shift;
my $product = shift;
if ( not defined $product or not $product->isa("Product") ) {
croak qq(Push Method for requires a Product Class to push);
}
my $array_ref = $self->_Array_ref;
push @{ $array_ref }, $product;
return $#{ $array_ref };
}
sub Pop {
my $self = shift;
my $array_ref = $self->_Array_ref;
return pop @{ $array_ref };
}
sub Next {
my $self = shift;
my $index = $self->Index;
my $array_ref = $self->_Array_ref;
$index += 1;
$self->Index($index);
return ${ $array_ref }[$index];
}
sub Prev {
my $self = shift;
my $index = $self->Index;
my $array_ref = $self->_Array_ref;
$index -= 1;
$self->Index($index);
return ${ $array_ref }[$index];
}
package main;
__DATA__
abc Dell Powerconnect-5600
abc Dell R-720
abc Dell R-920
123 Dell 210
123 Dell TZ-200
123 Dell TZ-200
答案 3 :(得分:0)
这也有效:
while (my ($build_num, $href) = each %$list) {
my ($branch, $aref, $username);
$aref = $href->{'products'};
$branch = $href->{branch};
$username = $href->{user};
for my $href (@$aref) {
print "product: $href->{prodtype} prodtype: $href->{product} qbs_id:$href->{qbs_id}\n";
}
刚刚编辑了@Chris答案并进行了一些简单的修改而不使用ref ..谢谢你