in reply to reduce like iterators

#!/usr/bin/perl # 2024-0111: From the node: "Eliminate consecutive duplicates of list # elements. If a list contains repeated elements they should be # replaced with a single copy of the element. The order of the # elements should not be changed." use strict; use warnings; { my @orig = qw/a a a a b c c a a d e e e e/; my @correct = qw/a b c a d e/; my @soln; for ( push ( @soln, shift @orig ); @orig; ) { my $val = shift @orig; if ( $soln[-1] ne $val ) { push ( @soln, $val ); } } print "Correct solution is @correct;\n"; print "My solution is @soln.\n"; }

Because my background (before Perl) is in C, that automatically looks like a for loop problem to me. In other words, you need to prime the pump so that you're not forced into doing something Really Clever for the first element.

And I could have written

push ( @soln, $val ) if ( $soln[-1] ne $val );
to make it more Perl-ish, but I'm not a fan of the postfix syntax. My OldSchool brain wants to see an if statement at the beginning of the line.

And, yes, this assumes that the list is string values (or stringable values), and does not deal with the undef value. That reminds me of a Google interview that I had a while back ("What about this ridiculous limitation to the solution?" "And how about this even more insane exception?").

Alex / talexb / Toronto

Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

Replies are listed 'Best First'.
Re^2: reduce like iterators
by hippo (Archbishop) on Jan 11, 2024 at 17:37 UTC
    push ( @soln, $val ) if ( $soln[-1] ne $val );

    The brackets around the arguments to push are unnecessary, even in the full-blown if-block you used. With postfix-if you can lose the other brackets too:

    push @soln, $val if $soln[-1] ne $val;

    I know some folks like the extra brackets but I find removing them aids clarity.


    🦛

      Sure, but then you're left with

        push @soln, $val if ( $soln[-1] ne $val );
      and with the comma suggesting do this thing, then do that other thing, it could read like this:
        push @soln # and then .. $val if ( $soln[-1] ne $val );
      Huh. That can't be right.

      You could also use indentation to make it clearer ..

        push @soln, $val if ( $soln[-1] ne $val );

      Anyway, it's a matter of taste, and my preferences comes from writing C in the 80's.

      Alex / talexb / Toronto

      Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

        That's why I prefer

        $soln[-1] ne $val and push @soln, $val;