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

The naive solution:
my $input='rnbqkbnr'; my $search='n'; my $index=0; my @result; foreach(split //,$input) { if($_ eq $search) { push(@result,$index); } $index++; } print "Result: ",join(' , ',@result);
Is there a shortcut to do it more simply?
  • Comment on How can one create an array of the indices at which a given character appears in a string?
  • Download Code

Replies are listed 'Best First'.
Re: How can one create an array of the indices at which a given character appears in a string?
by choroba (Cardinal) on Jan 29, 2015 at 13:02 UTC
    See index.
    #!/usr/bin/perl use warnings; use strict; my $input = 'rnbqkbnr'; my $search = 'n'; my @positions; my $pos = 0; while ($pos = 1 + index $input, $search, $pos) { push @positions, $pos - 1; } print "@positions\n";
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      Nice.
Re: How can one create an array of the indices at which a given character appears in a string?
by BrowserUk (Patriarch) on Jan 29, 2015 at 13:25 UTC
    my $input = 'rnbqkbnr'; my $search = 'n'; my @results = grep substr( $input, $_, 1 ) eq $search, 0 .. length $in +put; print @results; 1 6

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
    In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked
      I implemented this solution, so this code is already running in my program.
      # collect coords where this piece is found on the board my @pos = grep substr( $self->{rep}, $_, 1 ) eq $piece, 0 .. length $s +elf->{rep};
      Nice clean solution.
Re: How can one create an array of the indices at which a given character appears in a string?
by LanX (Saint) on Jan 29, 2015 at 13:25 UTC
    the @- and @+ dynamic arrays supply the indices of successful matches of X in m/(X)/g

    Cheers Rolf

    PS: Je suis Charlie!

      Exactly, how does this work? The following code prints 2 2 and not 1 6.

      use warnings; use strict; my $input = 'rnbqkbnr'; $input =~ /(n)/g; print "@+\n";

        Maybe I misunderstood perlvar and it doesn't work with /g in list context but only with repeated match groups in a non-global match.

        Anyway you should take @- for start, your results show the ends.

        Can't test ATM...sorry.

        update
        Without being able to test, please try

        print $-[0] while /n/g

        update

        now tested:

        DB<100> $_ = " x " x 3 => " x x x " DB<101> print $-[0] while /x/g 147

        Cheers Rolf

        PS: Je suis Charlie!

      What is the exact code here? The other solutions work for me ( I even understand how they work ), but I can't make this one work.
Re: How can one create an array of the indices at which a given character appears in a string?
by DanBev (Scribe) on Jan 29, 2015 at 13:11 UTC

    to my knowledge, the naive solution is ok. Just a few simplifications that do not change the logic of the program

    use strict; my @input= split("", 'rnbqkbnr'); my $search='n'; my @result; for (my $i = 0; $i < $#input; $i++) { push @result, $i if $input[$i] eq $search; } print "Result: ",join(' , ',@result);
Re: How can one create an array of the indices at which a given character appears in a string?
by ateague (Monk) on Jan 31, 2015 at 04:56 UTC
    TMTOWTDI

    Here's a way with pos() and regular expressions:

    use strict; use warnings; my $input = 'rnbqkbnr'; my $search = qr/n/; my @result; push @result, pos($input) - 1 while $input =~ /$search/cg; print "@result";