how to declare array reference in hash refrence

364 Views Asked by At
my $memType = [];
my $portOp = [];
my $fo = "aster.out.DRAMA.READ.gz";
    if($fo =~/aster.out\.(.*)\.(.*)\.gz/){
      push (@{$memType},$1);
      push (@{$portOp},$2);
    }
  print Dumper @{$memType};
  foreach my $mem (keys %{$portCapability->{@{$memType}}}){
//How to use the array ref memType inside a hash//
    print "entered here\n";
   //cannot post the rest of the code for obvious reasons//
}

I am not able to enter the foreach loop . Can anyone help me fix it? Sorry this is not the complete code . Please help me.

3

There are 3 best solutions below

0
On
%{$portCapability->{@{$memType}}}

This doesn't do what you may think it means.

  1. You treat $portCapability->{@{$memType}} as a hash reference.
  2. The @{$memType} is evaluated in scalar context, thus giving the size of the array.

I aren't quite sure what you want, but would

%{ $portCapability->{ $memType->[0] } }

work?

If, however, you want to slice the elements in $portCapability, you would need somethink like

@{ $portCapability }{ @$memType }

This evaluates to a list of hashrefs. You can then loop over the hashrefs, and loop over the keys in an inner loop:

for my $hash (@{ $portCapability }{ @$memType }) {
  for my $key (keys %$hash) {
    ...;
  }
}

If you want a flat list of all keys of the inner hashes, but don't need the hashes themselves, you could shorten above code to

for my $key (map {keys %$_} @{ $portCapability }{ @$memType }) {
  ...;
}
2
On

I think what you want is this:

my $foo = { 
  asdf => { 
    a => 1, b => 2, 
  }, 
  foo => {
    c => 3, d => 4 
  }, 
  bar => {
    e => 5, f => 6 
  }
};
my @keys = qw( asdf foo );

foreach my $k ( map { keys %{ $foo->{$_} } } @keys ) {
  say $k;
}

But you do not know which of these $k belongs to which key of $foo now.

There's no direct way to get the keys of multiple things at the same time. It doesn't matter if these things are hashrefs that are stored within the same hashref under different keys, or if they are seperate variables. What you have to do is build that list yourself, by looking at each of the things in turn. That's simply done with above map statement.

First, look at all the keys in $foo. Then for each of these, return the keys inside that element.

0
On
my $memType = [];
my $portOp = [];
my $fo = “aster.out.DRAMA.READ.gz”;
   if ($fo =~ /aster.out\.(\w+)\.(\w+)\.gz/ ) { #This regular expression is safer
    push (@$memType, $1);
            push (@$portOp, $2);
  }
print Dumper “@$memType”; #should print “DRAMA”
#Now if you have earlier in your program the hash %portCapability, your code can be:
foreach $mem (@$memType) { 
    print $portCapability{$mem};
}
#or if you have the hash $portCapability = {…}, your code can be:
foreach $mem (@$memType) {
    print $portCapability->{$mem};
} 
#Hope it helps