Reputation: 2277
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
Upvotes: 1
Views: 3220
Reputation: 240809
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.
Upvotes: 4