in reply to reduce like iterators

my @b = uniq @a; my %seen; my @b = grep !$seen{$_}++, @a;

But if you really want to use reduce with just one expression, it's definitely possible.

my @b = @{( reduce { push @{$a->[1]}, $b if !$a->[0]{$b}++ } [ {}, [] +], @a; $a )->[1]};

Replies are listed 'Best First'.
Re^2: reduce like iterators
by LanX (Saint) on Jan 03, 2011 at 18:53 UTC
    read the example again, it's not about uniq but identifying sequences!

    update:

    DB<1> use List::MoreUtils "uniq"; print uniq qw(a a a a b c c a a d +e e e e) abcde

    Cheers Rolf

      Oops, adjusted:

      my @b = @{ reduce { push @$a, $b if !@$a || $b ne $a->[-1]; $a } [], @ +a };

      If one were to make a list version of reduce, the callback would need access to three variables: The list (say $_), the state (say $a), the current value (say $b). The problem could be solved as follows:

      my @b = list_reduce { push @$_, $b if !@$_ || $b ne $_->[-1]; undef } +undef, @a; my @b = list_reduce { push @$_, $b if $a || $b ne $_->[-1]; 0 } 1, @a; my @b = list_reduce { push @$_, $b if defined($b) && $b ne $a; $b } un +def, @a; my @b = list_reduce { push @$_, grep defined && $_ ne $a, $b; $b } und +ef, @a;

      (@a may not start with undef for the last two to work properly.)

      Update: Added everything after the first block of code.

        > > my @b = @{ reduce { push @$a, $b if @$a && $b ne $a->[-1]; $a } [], @a };

        And I said:

        > (Sure I could use $a as an array-ref for accumulation, not very elegant...)

        Cheers Rolf