Ghostff
Ghostff

Reputation: 1458

mapping to a subroutine that accepts multiple argument

am trying to map an array to a subroutine that accept 2 argument, i tried using php array_map concept but didn't work out:

sub m {
   my ($n, $m) = @_;
   return("The number $n is called $m in Spanish");
}

sub new_map {
   my (@argument) = @_;
   my @arg = @argument;

   @array = map(m($_, $_), @{ $arg[0] }, @{ $arg[1]});
}

my @arr1 = (1, 2, 3);
my @arr2 = ("uno", "dos");
new_map(\@arr1, \@arr2);

#outputs
#The number 1 is called 1 in Spanish INSTEAD OF 'The number 1 is called uno in Spanish'
#The number 2 is called 2 in Spanish INSTEAD OF 'The number 1 is called dos in Spanish'

Is there a way to accomplish this.

Upvotes: 1

Views: 84

Answers (1)

ysth
ysth

Reputation: 98398

Your updated code that uses new_map could be done like so:

use Algorithm::Loops 'MapCarMin';

my @arr1 = (1, 2, 3);
my @arr2 = ("uno", "dos");
@array = MapCarMin \&m, \@arr1, \@arr2;

or

sub call_m_over_pair_of_arrays {
    my ($arrayref1, $arrayref2) = @_;
    map &m($arrayref1->[$_], $arrayref2->[$_]), 0..( $#$arrayref1 < $#$arrayref2 ? $#$arrayref1 : $#$arrayref2 );
}
@array = call_m_over_pair_of_arrays( \@arr1, \@arr2 );

Answer to original question:

Parentheses don't create lists or arrays in perl; nested parentheses just flatten out into a single list; you would need to do this:

@array = map( &m(@$_), [ 1, 'uno' ], [ 2, 'dos' ] );

Or this:

use List::Util 1.29 'pairmap';
@array = pairmap { &m($a, $b) } (1, 'uno', 2, 'dos');

Don't name subroutines m; that conflicts when the m match operator. (Though you can still call such a subroutine using &, it is better not to.)

Upvotes: 6

Related Questions