Question

I am trying to iterate over this data structure:

$deconstructed->{data}->{workspaces}[0]->{workspace}->{facts}[0]->{code}

where fact[0] is increasing. It's several files I am processing so the number of {facts}[x] varies.

I thought this might work but it doesn't seem to be stepping up the $iter var:

foreach $iter(@{$deconstructed->{data}->{workspaces}[0]->{workspace}->{facts}}){
  print $deconstructed->{data}->{workspaces}[0]->{workspace}->{facts}[$iter]->{code}."\n";
}

I'm totally digging data structures but this one is stumping me. Any advice what might be wrong here?

Was it helpful?

Solution

$iter is being set to the content of each item in the array not the index. e.g.

my $a = [ 'a', 'b', 'c' ];
for my $i (@$a) {
    print "$i\n";
}

...prints:

a
b
c

Try:

foreach $iter (@{$deconstructed->{data}->{workspaces}[0]->{workspace}->{facts}}){
    print $iter->{code}."\n";
}

OTHER TIPS

$iter is not going to be an index that you can subscript the array with, it is rather the current element of the array. So I guess you should be fine with:

$iter->{code}

Your $iter contains the data sctructure. What you basiclly want is:

foreach my $elem ( @{$deconstructed->{data}->{workspaces}[0]->{workspace}->{facts}} ){
    print $elem->{code};
}

or:

foreach my $iter ( 0 .. scalar @{$deconstructed->{data}->{workspaces}[0]->{workspace}->{facts}} ){
    print $deconstructed->{data}->{workspaces}[0]->{workspace}->{facts}[$iter]->{code}."\n";
}

Since you are looping over the array, your misnamed $iter is the value you are looking for, not an index. If you want to loop over the indexes instead, do:

foreach $iter ( 0 .. $#{$deconstructed->{data}->{workspaces}[0]->{workspace}->{facts}} ) {
    print "Index $iter: ",
        $deconstructed->{data}->{workspaces}[0]->{workspace}->{facts}[$iter]->{code}."\n";
}

Also note that you can drop -> between two [] or {}:

$deconstructed->{data}{workspaces}[0]{workspace}{facts}[$iter]{code}

I recommend reading http://perlmonks.org/?node=References+quick+reference.

When you have ugly data structures like this, make an interface for it so your life is easier:

 foreach my $fact ( $data_obj->facts ) {  # make some lightweight class for this
     ....;
     }

Even without that, consider using a reference to just the part of the data structure you need so you don't think about the rest:

 my $facts = $deconstructed->{data}{workspaces}[0]{workspace}{facts};
 foreach my $fact ( @$facts ) {
     print "Thing is $fact->{code}\n";
     }

It's just a reference, so you're not recreating anything. Since you only have to think about the parts beyond the facts key, the problem doesn't look as hard.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top