问题
Assume this structure of a Geo::Coder::Google
data dump --- dd $location;
.
address_components => [
{
long_name => "Blackheath Avenue",
short_name => "Blackheath Ave",
types => ["route"],
},
{
long_name => "Greater London",
short_name => "Gt Lon",
types => ["administrative_area_level_2", "political"],
},
{
long_name => "United Kingdom",
short_name => "GB",
types => ["country", "political"],
},
{
long_name => "SE10 8XJ",
short_name => "SE10 8XJ",
types => ["postal_code"],
},
{ long_name => "London", short_name => "London", types => ["postal_town"] },
],
formatted_address => "Blackheath Avenue, London SE10 8XJ, UK",
geometry => {
bounds => {
northeast => { lat => 51.4770228, lng => 0.0005404 },
southwest => { lat => 51.4762273, lng => -0.0001147 },
},
location => { lat => 51.4766277, lng => 0.0002212 },
location_type => "APPROXIMATE",
viewport => {
northeast => { lat => 51.4779740302915, lng => 0.00156183029150203 },
southwest => { lat => 51.4752760697085, lng => -0.00113613029150203 },
},
},
types => ["route"],
}
An example call:
my $long_name = &get_field_for_location("long_name", $location);
Following sub returns the first long_name
(in this example --- type=route):
sub get_field_for_location($$) {
my $field = shift;
my $location = shift;
my $address = $location->{address_components};
return $_->{$field} for @$address;
}
How to access a long_name
of another type? i.e. how to modify this sub to access a $field
for a given type entry?
回答1:
It should return first of type political
,
my $type = "political";
my ($first_of_type) = grep {
grep { $_ eq $type } @{$_->{types}};
} @$address;
return $first_of_type->{$field};
Outer grep
filters elements of @$address
array, and inner grep
filters elements of types
, ie. ["administrative_area_level_2", "political"]
回答2:
types
is a reference to an array of strings. You will need to check if any of them matches the required type. You can do this using List::Util::first:
use List::Util qw(first);
sub get_field_for_location {
my $field = shift;
my $location = shift;
my $type = shift;
my $address = $location->{'address_components'};
for my $component (@{$address}) {
if (first { $_ eq $type } @{$component->{'types'}}) {
return $component->{$field};
}
}
}
来源:https://stackoverflow.com/questions/19570737/how-to-access-a-specific-value-of-a-key-within-a-perl-structure