I have a set of five boolean values. If more than one of these are true I want to excecute a particular function. What is the most elegant way you can think of that would al
If your flags are packed into one word then Michael Burr's solution will work. However, the loop is not necessary:
int moreThanOneBitSet( unsigned int v)
{
return (v & (v - 1)) != 0;
}
example
v (binary) | v - 1 | v&(v-1) | result
------------+-------+---------+--------
0000 | 1111 | 0000 | false
0001 | 0000 | 0000 | false
0010 | 0001 | 0000 | false
0011 | 0010 | 0010 | true
.... | .... | .... | ....
1000 | 0111 | 0000 | false
1001 | 1000 | 1000 | true
1010 | 1001 | 1000 | true
1011 | 1010 | 1010 | true
1100 | 1011 | 1000 | true
1101 | 1100 | 1100 | true
1110 | 1101 | 1100 | true
1111 | 1110 | 1110 | true
Casting to ints and summing should work, but it's a bit ugly and in some languages may not be possible.
How about something like
int count = (bool1? 1:0) + (bool2? 1:0) + (bool3? 1:0) + (bool4? 1:0) + (bool5? 1:0);
Or if you don't care about space, you could just precompute the truth table and use the bools as indices:
if (morethanone[bool1][bool2][bool3][bool4][bool5]) {
... do something ...
}
if((b1.CompareTo( false ) + b2.CompareTo( false ) + b3.CompareTo( false ) + ...) > 1)
// More than one of them are true
...
else
...
While I like LINQ, there are some holes in it, like this problem.
Doing a count is fine in general, but can become an issue when the items your counting take a while to calculate/retrieve.
The Any() extension method is fine if you just want to check for any, but if you want to check for at least there's no built in function that will do it and be lazy.
In the end, I wrote a function to return true if there are at least a certain number of items in the list.
public static bool AtLeast<T>(this IEnumerable<T> source, int number)
{
if (source == null)
throw new ArgumentNullException("source");
int count = 0;
using (IEnumerator<T> data = source.GetEnumerator())
while (count < number && data.MoveNext())
{
count++;
}
return count == number;
}
To use:
var query = bools.Where(b => b).AtLeast(2);
This has the benefit of not needing to evaluate all the items before returning a result.
[Plug] My project, NExtension contains AtLeast, AtMost and overrides that allow you to mix in the predicate with the AtLeast/Most check. [/Plug]
I wanted to give a C++11 variadic template answer.
template< typename T>
T countBool(T v)
{
return v;
}
template< typename T, typename... Args>
int countBool(T first, Args... args)
{
int boolCount = 0;
if ( first )
boolCount++;
boolCount += countBool( args... );
return boolCount;
}
simply calling it as follows creates a rather elegant method of counting the number of bools.
if ( countBool( bool1, bool2, bool3 ) > 1 )
{
....
}
from the top of my head, a quick approach for this specific example; you could convert the bool to an int (0 or 1). then loop through therm and add them up. if the result >= 2 then you can execute your function.