in reply to Creating a text index for a text file

I think this should be a good exercise and learning experience for you. There are many solutions ...

Solution 1
#!/usr/local/bin/perl -w use strict; my %letter; while (<DATA>) { print("$_"), next if /^\s*$/; # print and skip empty lines my $c = substr $_, 0, 1; # get first character if (! exists $letter{$c}) { # have we seen it before? $letter{$c}++; print ":$c:\n"; } print; } __DATA__ AA for apple A for apple BB for ball B for ball C for ....
And the output is -
:A: AA for apple A for apple :B: BB for ball B for ball :C: C for ....
Solution 2
A more perl-ish solution, with regular expressions
#!/usr/local/bin/perl -w use strict; my %letter; foreach (<DATA>) { s/^(.)/$letter{$1}++ ? $1 : ":$1:\n$1"/e; print; } __DATA__ AA for apple A for apple ...
Solution 3
Another variant, read the file into a scalar and do search and replace in one go:
#!/usr/local/bin/perl -w use strict; local $/; my $data = <DATA>; my %letter; $data =~ s/^(.)/$letter{$1}++ ? $1 : ":$1:\n$1"/emg; print "$data"; __DATA__ AA for apple A for apple ...

Replies are listed 'Best First'.
Re: Re: Find
by sgifford (Prior) on Nov 26, 2003 at 09:34 UTC
    We really don't need to keep a hash of letters, since the file is already sorted. We just need to keep track of what the last letter seen was:
    #!/usr/local/bin/perl -w use strict; my $lastlet; while (<DATA>) { print, next if /^\s*$/; # print and skip empty lines my $c = uc substr $_, 0, 1; # get first character print ":$c:\n" if (!$lastlet || $lastlet ne $c); $lastlet = $c; print; } __DATA__ AA for apple A for apple BB for ball B for ball C for ....
Re: Re: Find
by texuser74 (Monk) on Nov 26, 2003 at 09:30 UTC

    Your Solution 1 is fabulous, i am adopting it

    many thanks

    raj

      No problem. ;-)

      By the way, solution 1 can be simplified further -
      #!/usr/local/bin/perl -w use strict; my %letter; while (<DATA>) { print, next if /^\s*$/; my $c = substr $_, 0, 1; print ":$c:\n" if ! $letter{$c}++; print; } __DATA__ AA ... A..
      Hey, didn't you like my second and third solutions? ;-)

        i am new to perl. At first glance, i was only able to understand your Solution 1. Rest i am still trying to figure out...

        howz little Albert doing, congrats...

        thanks for all perl monks

Re: Re: Find
by duff (Parson) on Nov 26, 2003 at 15:19 UTC
    I think this should be a good exercise and learning experience for you.
    Then you proceed to give him answers! Fish giver! But you're not alone, there is much shameful homework-doing in response to this node. :-)