imbatman
imbatman

Reputation: 518

GetOption - Perl - Referencing

So I have stumbled upon a little issue when trying to build out a simple "Airport Search Script" in Perl.

my $filename = '/home/student/perl-basic/topic-07/iata_airports.csv';
my $number = '1';
my $matching;
my $latitude;
my $longitude;
my $word = 'false';

GetOptions (
        "filename=s"    =>      \$filename,
        "number=i"      =>      \$number,
        "matching=s"    =>      \$matching,
        "latitude=f"    =>      \$latitude,
        "longitude=f"   =>      \$longitude,
        "word=s"        =>      \$word
);

sub parse_airports {

        my $file = shift;

        my $csv = Text::CSV->new( { binary => 1, eol => $/ } );

        open ( my $fh, "<", $file ), or die "Error opening input file: $!";

                my $ra_colnames = $csv->getline ( $fh );
                        $csv->column_names( @$ra_colnames );

                my $ra_airports = $csv->getline_hr_all( $fh );

        close ( $fh );

        return $ra_airports;

}

sub get_name_matching_airports {



}

my $rah_airports = parse_airports( $filename );
my $rah_airports_found = [];

if ($matching) {
  say "Up to $number airports matching $matching in $filename:";
        $rah_airports_found = get_name_matching_airports(
        airports        => $rah_airports,
        matching_string => $matching,
        word            => $word,
  );
}
elsif ($latitude && $longitude) {
  say "Up to $number airports near [$latitude, $longitude] in $filename:"
}
else {
  say "Must have at least --matching, or --latitude and --longitude as arguments";
}

print pp($rah_airports_found);

So where I am struggling is in the "sub get_name_matching_airports"

Because you do not have the file let me explain the file structure. It is a hash (ALL IATA Airports) with hashes (DETAILS of each airport). There are around 15 keys in each airport hash and one of the keys titles is (NAME). I have opened the file and parsed all the info into a hash ref which is returned at the end of the sub "parse_airports".

In the sub "get_name_matching_airports" I need to find additional airports with similar names based on the argument I passed in, into ($matching).

EXAMPLE: I parse (case-insensitive) "London" as an argument from the command line e.g. ./search_airports2 --matching London. In the sub "get_name_matching_airports" I will need to respond with any airport that has london (case-insensitive) in key(name).

Then push these newly found airports which are similar into the array "rah_airports_found" and in the end print this out.

SO I SOLVED MY PROBLEM WITH THE FOLLOWING CODE:

sub get_name_matching_airports {

        my %params = (
                airports        => undef,
                matching_string => undef,
                word            => undef,
                @_
        );

        my @rah_airports_found;

        my $ra_airports = $params{airports};
        my $counter = 0;

        foreach my $i ( @$ra_airports ) {
                if ( $params{word} ) {
                        if ( $i->{name} eq $params{matching_string} ) {
                                push @rah_airports_found, $i;
                                $counter++;
                                }
                        }
                        else {
                        if ( $i->{name} =~ /$params{matching_string}/i ) {
                                push @rah_airports_found, $i;
                                $counter++;
                        }
                        if ( defined( $number ) && $counter == $number ) {
                                return \@rah_airports_found;
                        }
                }
        }

        return \@rah_airports_found;

}

Upvotes: 0

Views: 188

Answers (1)

JMa
JMa

Reputation: 66

Example:

for my $Airport_rf (keys %{$rah_airports}) {
    if ( $Airport_rf->{NAME} =~ m{\Q$matching\E}xi) {
        # do your stuff here
    }
}

If you don´t know the exact key of the hashref, you have to match the CLI parameter against all values.

Upvotes: 1

Related Questions