1

I have the following structure:

my @fields = (
    {
        "dbId"        => "BabysSex",
        "db2Id"       => "DetSex",
        "name"        => "Baby's Sex",
        "datatype"    => "Text",
        "outputorder" => 5,
        "value" => undef,
    },
    {
        "dbId"     => "HospitalCode",
        "name"     => "Hospital Code",
        "datatype" => "Text",
        "value" => undef,
    },
    {
        "dbId"        => "UniqueIdenifier",
        "name"        => "Unique Identifier",
        "datatype"    => "Text",
        "outputorder" => 7,
        "value" => undef,
    },

);

After assigning the values to each $filed[$i]->{"value"}, I need to do some further processing and expansion. For instance, the data set I am processing uses digits to represent different values for sex (eg 1 for male, 2 for female and so on). I can expand this in a for loop:

for ( my $i = 0 ; $i < scalar @fields ; $i++ ) {
   if ( $fields[$i]->{"name"} =~ /sex/i && $fields[$i]->{"value"} )
   {
      $fields[$i]->{"value"} = $SexMap{ $fields[$i]->{"value"}};
   }
}

What I would like to know is if I can use map to get the same results.

Thanks

1
  • 1
    Your loop can be abbreviated to for my $i (0..$#fields) {...} — read: foreach value $i in the range from 0 to the highest index in @fields. @hobbs solution is even cleaner. map is used best for "piping" list to another command, I feel: print join "-", map {$_?'ZERO'} (0..5);` not for complex in-place edits Commented Aug 17, 2012 at 2:14

1 Answer 1

4

You can, yes, but I'm not convinced that it would be right, and it's definitely not necessary.

I would begin by rewriting your code as

for (@fields) {
    $_->{value} = $SexMap{ $_->{value} } if $_->{name} =~ /sex/i and $_->{value};
}

Which works just fine because a foreach aliases $_ to each element in the array.

It could be turned into a map like

@fields = map {
    $_->{value} = $SexMap{ $_->{value} } if $_->{name} =~ /sex/i and $_->{value};
    $_;
} @fields;

but you'll notice that the map isn't actually doing anything here, it's just adding code.

If the reason that you want a map is to create a copy without modifying the original, then

@newfields = map {
    ($_->{name} =~ /sex/i and $_->{value})
    ? ( { %$_, value => $SexMap{ $_->{value} } } )
    : ( { %$_ } )
} @fields;

which does a shallow copy of each element (and therefore the map actually accomplishes something) but there are probably cleaner ways to accomplish that.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.