in reply to One out of three ain't bad
I'm not convinced that you need an elegant solution to finding if one and only one of three elements evaluates to truth. But it's kind of a fun problem anyway, and if the number of elements grows, a sleek solution becomes more relevant. So here goes...
Try cpan's List::MoreUtils:
use strict; use warnings; use List::MoreUtils qw/ true /; my @lists = ( [ 1, 0, 1 ], [ 1, 0, 0 ], [ 1, 1, 1 ], [ 0, 0, 0 ] ); foreach my $aref ( @lists ) { print "Testing @{$aref}\n"; print "Total list Exclusive OR ", ( 1 == true { $_ } @{ $aref } ) ? '' : 'not ', "satisfied.\n\n"; }
Here we're just using the true() function from List::MoreUtils. The function returns the number of true elements. Like one of your proposed solutions, we simply check to ensure that the number of true elements is exactly one. This one works almost identically to your grep solution, except that it uses an explicit function name (true()) instead of a generic one such as grep.
My example snippet actually tests a list of lists to see if each sub-list individually satisfies your requirement of a single element of truth. The engine is this:
1 == true { $_ } @arrayIf that test evaluates to truth, you've got a list with a single element of truth.
Dave
|
|---|