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

Dear Monks, I have an array and a string.

$string = "ASDFGHJ"; @array = ("|", "|", "|", "|", "", "|", "|");

What I want is to find which element of the array is "" and change the corresponding letter in the string to lowercase letter; In this case it would be "ASDFgHJ". I have a vague idea on how to do it but there must be a easy single loop solution. There can be more than one "" elements and all of the corresponding letters need to be changed. Thank for your help! Tom

Replies are listed 'Best First'.
Re: Array indexing and string manipulation
by tobyink (Canon) on Mar 26, 2012 at 16:21 UTC
    for my $i (0 .. $#array) { substr($string, $i, 1) = lc substr($string, $i, 1) if $array[$i] eq q(); }

    Update: As always, TIMTOWTDI...

    $altered_string = join q(), map { my $char = substr($string, $_, 1); $array[$_] eq q() ? lc($char) : $char; } 0 .. length $string;
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Array indexing and string manipulation
by davido (Cardinal) on Mar 26, 2012 at 16:48 UTC

    This probably has all the efficiency of Schlemiel the Painter, but it has some humor value:

    !$array[$_] && $string =~ s/(?<=^.{$_})(.)/lc $1/e for 0 .. $#array;

    Silly at best, but it works. :)

    This isn't as fun, but doesn't suffer from a lookbehind assertion that grows as the index increases:

    !$array[$_] and substr( $string, $_, 1 ) = lc substr( $string, $_, 1 ) for 0 .. $#array;

    Dave

Re: Array indexing and string manipulation
by Anonymous Monk on Mar 26, 2012 at 16:26 UTC
    my @array = ("|", "|", "|", "|", "", "|", "|"); print join '', map { my $foo = shift @array ? $_ : lc } split '', 'ASD +FGHJ';

      This is quite a nice technique. It's worth pointing out though, that it has a side-effect of dismantling @array, so you should make a copy of @array first if you were planning on using the array again.

      perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

      Worked like a charm, thanks. The first reply for some reason did not and returned all upper case letters. Seems I don't know perl as good as I thought ;].

      Any idea how to change it to catch " " instead of ""? Thanks
Re: Array indexing and string manipulation
by ikegami (Patriarch) on Mar 26, 2012 at 17:21 UTC
    Works for strings of containing just A-Z.
    $string |= join '', map chr( $_ ? 0 : 040 ), @array;
Re: Array indexing and string manipulation
by JavaFan (Canon) on Mar 26, 2012 at 16:44 UTC
    $array[$_] or substr($string, $_, 1) |= "\x20" for 0 .. $#array;
    This will not work for letters with code points exceeding 255.
Re: Array indexing and string manipulation
by jwkrahn (Abbot) on Mar 26, 2012 at 21:45 UTC
    $ perl -le' my $string = "ASDFGHJ"; my @array = ( "|", "|", "|", "|", "", "|", "|" ); print $string; $string =~ s/(.)/ length $array[ $-[ 0 ] ] ? $1 : lc $1 /eg; print $string; ' ASDFGHJ ASDFgHJ