papaiatis papaiatis - 15 days ago 6
Perl Question

Perl: pair elements in two list

I have two lists:

my @prefixes = ["abc", "def", "ghi", "jklmn"];
my @strings = ["abc123", "def456", "jklmnopqrst"];


I need to find the correct prefix for each string so that "abc123" belongs to "abc" and "def456" belongs to "def" and "jklmnopqrst" belongs to "jklmn".
All strings has a prefix in @prefixes but not all prefix has a matching string (see "ghi").

I have this code:

use List::Util qw(first);
...
foreach my $str (@strings) {
my $prefix = first { $_ eq substr($str, 0, length($_)) } @prefixes;
print "$prefix\n";
# do something with $str and $prefix together
}


But it's not working, I'm getting
Use of uninitialized value $prefix in concatenation (.) or string


What's wrong?

UPDATE: So it was an easy fix. I should have initialized my lists using () and not []. To not to close this yet, how would you get rid of the
foreach
statement?

Answer

In place of the foreach you could use map, however, the code becomes considerably less readable.

#!/usr/bin/env perl

use strict;
use warnings;

use List::Util qw/ first /;

my @prefixes = ("abc", "def", "ghi", "jklmn");
my @strings = ("abc123", "def456", "jklmnopqrst");

# foreach my $str ( @strings ) {
#   my $prefix = first { $_ eq substr( $str, 0, length( $_ )) } @prefixes;
#   print $prefix, "\n";
# }

my @found  = map { my $str = $_; first { $_ eq substr( $str, 0, length( $_ ))} @prefixes } @strings;

print join("\n", @found), "\n";