in reply to reduce like iterators
Hi LanX,
map{} will pass on undef's, but grep{} needs undef to tell whether something passed the filter. But you can stack any number of maps and greps together, which is how I came up with a workaround for it, using two maps and a grep.
The first map{}, reading from the bottom up, simply marks duplicates in-a-row (as opposed to any dupes at all) by changing them to 'aardvark'. Undef's and zeroes go through without problem. The second map{} changes actual undefined elements to the text 'undef'. Change these as suits your algorithm. The grep{} is where the duplicates/aardvarks are finally removed.
It seems to work, accommodating undefined values, while still being simple enough to use in a one-liner, and uses array refs so it doesn't pass whole lists back and forth.
And the one-liner -- actually broken up for easier viewing:use strict; my @orig = ( qw(a a b b c 0 c d d u u), (undef, undef, 'blink', 'blink'), qw(0 0 v v w w a a a b b b c c c) ); my @list; nodupes (\@orig, \@list); print join ' ', @list, "\n"; sub nodupes { my ($ar1, $ar2) = @_; my $p; push @$ar2, grep{$_ ne 'aardvark'} map{defined $_ ? $_ : 'undef'} map { $p ne $_ ? $p = $_ : 'aardvark' } @$ar1; } __END__ Prints --> a b c 0 c d u undef blink 0 v w a b c
perl -e "@list = grep{$_ ne 'aardvark'} map{defined $_ ? $_ : 'undef'} map{$p ne $_ ? $p = $_ : 'aardvark'} (qw(a a b b c 0 c u u), (undef, undef), qw(0 0 v v w w)); print join ' ', @list;" Prints --> a b c 0 c u undef 0 v w
I hope you find this interesting/useful.
--marmotUPDATE: I was thinking about this some more, and realized I had made it waaaay too complicated. The nodupes() below pretty much is a one-liner, and accomodates 0, "0", and undef just fine. And nodupes() can be used inline with other maps and greps. In the end, the grep was the only thing needed.
use strict; sub nodupes { my $p; return grep{ $_ ne '~~' } map { $p ne $_ ? $p = $_ : '~~' } @_; } my @orig = ( qw(a a b b c 0 c d d u u), (undef, undef, 'blink', 'blink'), qw(0 0 v v "0" "0" "0" w w a a a b b b c c c) ); my @new = nodupes @orig; print join ' ', @new, "\n"; __END__ Prints --> a b c 0 c d u blink 0 v "0" w a b c ^^ There's an undef between these two spaces.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re^2: reduce like iterators
by Anonymous Monk on Jan 12, 2011 at 15:52 UTC | |
by furry_marmot (Pilgrim) on Jan 15, 2011 at 23:48 UTC | |
by LanX (Saint) on Jan 16, 2011 at 11:22 UTC | |
by Anonymous Monk on Jan 17, 2011 at 22:47 UTC | |
by furry_marmot (Pilgrim) on Jan 18, 2011 at 23:52 UTC | |
by LanX (Saint) on Jan 19, 2011 at 00:09 UTC | |
by tilly (Archbishop) on Jan 19, 2011 at 01:14 UTC | |
| |
by furry_marmot (Pilgrim) on Jan 19, 2011 at 01:59 UTC |