I
Irving Kimura
I must admit that one of the things I enjoy most about programming
Perl is also one of the most infamous: the possibility of compact
expressions that get a lot done with very few keystrokes. I'm
referring to gems like this one:
# removes duplicates from an array, preserving original order
@no_repeats = do { my %h; grep !$h{$_}++, @has_repeats };
....which I found recently in an old c.l.p.m. post, and which make
Pythonites clutch their heads and run out of the room screaming.
OK, so call such opaque compactness a guilty pleasure, to be enjoyed
only by consenting adults...
I'm looking for the most compact way in Perl to take the logical
and of all the elements of an array or list. The best I can come
up with is this:
!grep !$_, @array;
(The corresponding logical or is equally long:
!!grep $_, @array;
The initial !! ensures a scalar result even in a list context.)
I've also run into stuff like this
eval join '&', map $_ ? 1 : 0, @array;
....which is a bit klugey but functional, and generalizable to other
infix operators such as '|' and '+'. Then again, generalizability
earns one no points in the compactness derby. (The map is required
to take care of cases in which @array contains elements, such as
the empty string or undef or whitespace, that would mess up the
Perl string to be eval'd. And since we are now dealing with 1s
and 0s we can take the bit-wise and.)
I wonder if there's anything better, or I should say badder, out
there. >
Irv
Perl is also one of the most infamous: the possibility of compact
expressions that get a lot done with very few keystrokes. I'm
referring to gems like this one:
# removes duplicates from an array, preserving original order
@no_repeats = do { my %h; grep !$h{$_}++, @has_repeats };
....which I found recently in an old c.l.p.m. post, and which make
Pythonites clutch their heads and run out of the room screaming.
OK, so call such opaque compactness a guilty pleasure, to be enjoyed
only by consenting adults...
I'm looking for the most compact way in Perl to take the logical
and of all the elements of an array or list. The best I can come
up with is this:
!grep !$_, @array;
(The corresponding logical or is equally long:
!!grep $_, @array;
The initial !! ensures a scalar result even in a list context.)
I've also run into stuff like this
eval join '&', map $_ ? 1 : 0, @array;
....which is a bit klugey but functional, and generalizable to other
infix operators such as '|' and '+'. Then again, generalizability
earns one no points in the compactness derby. (The map is required
to take care of cases in which @array contains elements, such as
the empty string or undef or whitespace, that would mess up the
Perl string to be eval'd. And since we are now dealing with 1s
and 0s we can take the bit-wise and.)
I wonder if there's anything better, or I should say badder, out
there. >
Irv