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

Hey all, quick, simple question that I can't seem to get right....

I have an array where most elements are words, but periodically, an element will be a simple left or right bracket, [ or ]. If I am looping throught the array, and I want to join the bracket element and the two trailing elements, why doesn't this work?:

if ($array[$i] eq '[') { $array[$i] = join ('', $array[$i],$array[$i+1],$array[$i+2]); }
I've also tried the following permutations, and none of them work:
if ($array[$i] eq q{[}) { #etc... if ($array[$i] eq "[") { #etc...
What silly little thing am I forgetting/missing/screwing up?

Thanks,
Matt
(back after a long hiatus)

Replies are listed 'Best First'.
Re: Test if variable is equal to a bracket?
by jdporter (Paladin) on May 16, 2007 at 21:59 UTC

    What do you mean by "doesn't work"? What, exactly, are you expecting?

    Note that your join statement modifies $array[$i], but leaves $array[$i+1] and $array[$i+2] unaltered.

    A word spoken in Mind will reach its own level, in the objective world, by its own weight
      Good point. Here's what I'm expecting... If: @array = ('A','B','C','[','D',']','E','F'); The result I want would be:  'A','B','C','[D]','E','F' Instead, @array is left untouched.

      As for leaving $array[$i+1] and $array[$i+2] unaltered, I take care of them in the next line.

      Thanks though for the concern....
      Matt

        Hi mdunnbass,

        There's nothing wrong with your comparison if ($array[$i] eq '['); rather, I'm guessing it's a problem with the way you're iterating over the array, and trying to change it in-place.

        I would recommend you use a temporary array for this, as it's easier to process, and there's no chance of messing up the original:

        #!/usr/local/bin/perl use strict; use warnings; use Data::Dumper; my @array = ('A','B','C','[','D',']','E','F'); my @results = ( ); while (@array) { my $string = shift @array; if ($string eq '[' and @array > 2) { $string .= (join "", splice(@array, 0, 2)); } push @results, $string; } printf "Results => %s\n", Dumper(\@results);

        s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
        This seems to work:
        use strict; my @array = qw/A B C [ D ] E F/; my @outarray; my $outid = 0; my $incrm = 1; for my $ch ( @array ) { $outarray[$outid] .= $ch; $incrm = ( $ch eq '[' ) ? 0 : ( $ch eq ']' ) ? 1 : $incrm; $outid += $incrm; } print "@outarray\n";
Re: Test if variable is equal to a bracket?
by johngg (Canon) on May 17, 2007 at 09:33 UTC
    If you want to modify the array in place without creating a new array you can use splice. Because that is altering the number of elements in the array, you have to work in from the right.

    use strict; use warnings; my @arr = qw{[ A ] B C [ D ] E F [ G ] H I}; my $idx = $#arr; while ( $idx >= 2 ) { if ( $arr[$idx] eq q{]} ) { splice @arr, $idx - 2, 0, join q{}, splice @arr, $idx - 2, 3; $idx -= 3; } else { $idx --; } } print qq{$_\n} for @arr;

    The output is

    [A] B C [D] E F [G] H I

    I hope this is useful.

    Cheers,

    JohnGG