Kevin
Kevin

Reputation: 1614

Loop 1st element of 2d List

I have a list like this

[[hash,hash,hash],useless,useless,useless]

I want to take the first element of hashes and loop through it - i try this:

my @list = get_list_somehow();
print Dumper($list[0][0]); print Dumper($list[0][1]);print Dumper($list[0][2]);

and i am able to access the elements fine manually, but when i try this

my @list = get_list_somehow()[0];
print Dumper($list[0]); print Dumper($list[1]);print Dumper($list[2]);
foreach(@list){
         do_something_with($_);
}

only $list[0] returns a value (the first hash, everything else is undefined)

Upvotes: 0

Views: 60

Answers (3)

Dave Gray
Dave Gray

Reputation: 723

I'm guessing a bit on your data structure here:

my $list = [
  [ { a => 1,
      b => 2,
      c => 3, },
    { d => 4, }
    { e => 5, }
  ], undef, undef, undef,
];

Then we get the 0th (first) element of the top-level array reference, which is another array reference, and then the 0th (first) element of THAT array reference, which is the first hash reference:

my $hr = $list->[0][0];

And iterate over the hash keys. That could also be written as one step: keys %{ $list->[0][0] }. It's a bit easier to see what's going on when broken out into two steps.

for my $key (keys %$hr) {
  printf "%s => %s\n", $key, $hr->{$key};
}

Which outputs:

c => 3
a => 1
b => 2

Upvotes: 0

David W.
David W.

Reputation: 107040

I'm taking that your sample data looks like this:

my @data = [
               {
                   one   => 1,
                   two   => 2,
                   three => 3,
               },
               "value",
               "value",
               "value",
           ];

That is, the first element of @data, $data[0] is your hash. Is that correct?

Your hash is a hash reference. That is the $data[0] points to the memory location where that hash is stored.

To get the hash itself, it must be dereferenced:

my %hash = %{ $data[0] };   # Dereference the hash in $data[0]
for my $key ( keys %hash ) {
    say qq( \$hash{$key} = "$hash{$key}".);
}

I could have done the dereferencing in one step...

for my $key ( keys @{ $data[0] } ) {
    say qq(\$data[0]->{$key} = ") . $data[0]->{$key} . qq(".);
}

Take a look at the Perl Reference Tutorial for information on how to work with references.

Upvotes: 0

TLP
TLP

Reputation: 67900

You are taking a subscript [0] of the return value of get_list_somehow() (although technically, you need parentheses there). What you need to do is to dereference the first element in that list. So:

my @list = get_list_somehow();
my $first = $list[0];              # take first element
my @newlist = @$first;             # dereference array ref

Of course, this is cumbersome and verbose, and if you just want to print the array with Data::Dumper you can just do:

print Dumper $list[0];

Or if you just want the first array, you can do it in one step. Although this looks complicated and messy:

my @list = @{ (get_list_somehow())[0] };

The @{ ... } will expand an array reference inside it, which is what hopefully is returned from your subscript of the list from get_list_somehow().

Upvotes: 3

Related Questions