SuzuBell has asked for the wisdom of the Perl Monks concerning the following question:

I do not have a firm understanding of this in Perl. Basically, I am comparing each character across a number of same-length strings. However, the code needs to be adaptable so that I do not want to "hard code" the number of characters per string or the number of strings. For instance, when I hard code a situation where there are only four strings, I have this:
for my $i ( 0 .. $lengthString - 1 ) { my $char0 = substr( $string0, $i, 1 ); my $char1 = substr( $string1, $i, 1 ); my $char2 = substr( $string2, $i, 1 ); my $char3 = substr( $string3, $i, 1 ); } }
But, can I update this code so that there is a second loop for each $char and $string between incrementation of an integer variable, say j? For instance:
for my $i ( 0 .. $lengthString - 1 ) { for my $j (0 .. $numChars - 1){ // The following line does not work my $char$j = substr( $string$j, $i, 1 ); } }

Replies are listed 'Best First'.
Re: Interpolate variable name in Perl?
by Eily (Monsignor) on Oct 24, 2013 at 16:07 UTC

    Yes you could do that with symbolic references, but you could actually just use an array @char, so that your characters would be stored in $char[0], $char[1], $char[2]. Besides, there's a simpler way to divide a string into chars : @char = split //, $string;

    And if you want to have "automatic variable name" instead of "automatic variable number", you should use a hash instead of the array. Have a look at perldsc for more information on the subject.

Re: Interpolate variable name in Perl?
by Kenosis (Priest) on Oct 24, 2013 at 16:25 UTC

    The following echoes Eily's suggestion:

    use strict; use warnings; my @AoA; while (<DATA>) { chomp; push @AoA, [ split '' ]; } for my $i ( 0 .. @AoA - 1 ) { for my $j ( 0 .. @{ $AoA[0] } - 1 ) { print "String $i; Char $j: '$AoA[$i]->[$j]'\n" } print "\n"; } __DATA__ String 1. Another 2 abcdefghi

    Output:

    String 0; Char 0: 'S' String 0; Char 1: 't' String 0; Char 2: 'r' String 0; Char 3: 'i' String 0; Char 4: 'n' String 0; Char 5: 'g' String 0; Char 6: ' ' String 0; Char 7: '1' String 0; Char 8: '.' String 1; Char 0: 'A' String 1; Char 1: 'n' String 1; Char 2: 'o' String 1; Char 3: 't' String 1; Char 4: 'h' String 1; Char 5: 'e' String 1; Char 6: 'r' String 1; Char 7: ' ' String 1; Char 8: '2' String 2; Char 0: 'a' String 2; Char 1: 'b' String 2; Char 2: 'c' String 2; Char 3: 'd' String 2; Char 4: 'e' String 2; Char 5: 'f' String 2; Char 6: 'g' String 2; Char 7: 'h' String 2; Char 8: 'i'

    $AoA[$i]->[$j] explained:

    $AoA[$i]->[$j] ^ ^ ^ | | | | | + - Character number in string | + - Dereferencing arrow + - String number in array

    The above builds an array of arrays (AoA) by splitting each string on an empty string to create a list of the string's characters in an anonymous array whose reference is pushed onto @AoA. The nested loops iterate through the AoA, using the dereferencing arrow -> to access each character. The notation @{ $AoA[0] } - 1 was used to obtain the number of characters in the dereferenced array (effectively the string length), since you mentioned that each string had the same length.

    Hope this helps!

Re: Interpolate variable name in Perl?
by Marshall (Canon) on Oct 24, 2013 at 22:14 UTC
    Basically, I am comparing each character across a number of same-length strings
    You might get a better answer if you explained how this character comparison works (compare each character to what)?

    In Perl often a regex (regular expression) is what you need for this sort of situation. Also it is seldom necessary to use numeric indicies (or course, seldom does not mean "never"). Perl has a lot of cool iterators to process arrays and other structures of things without using an explicit index. That is actually very cool since right at the top of common coding errors is the "off by one" problem.

    Anyway you dived pretty quick into asking how to access a string of characters as an array and it might be that what you really need to know is actually something else.