Search code examples
c#hammingweight

Elegantly determine if more than one boolean is "true"


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 allow me to check this condition in a single if() statement? Target language is C# but I'm interested in solutions in other languages as well (as long as we're not talking about specific built-in functions).

One interesting option is to store the booleans in a byte, do a right shift and compare with the original byte. Something like if(myByte && (myByte >> 1)) But this would require converting the separate booleans to a byte (via a bitArray?) and that seems a bit (pun intended) clumsy... [edit]Sorry, that should have been if(myByte & (myByte - 1)) [/edit]

Note: This is of course very close to the classical "population count", "sideways addition" or "Hamming weight" programming problem - but not quite the same. I don't need to know how many of the bits are set, only if it is more than one. My hope is that there is a much simpler way to accomplish this.


Solution

  • How about

      if ((bool1? 1:0) + (bool2? 1:0) + (bool3? 1:0) + 
          (bool4? 1:0) + (bool5? 1:0) > 1)
          // do something
    

    or a generalized method would be...

       public bool ExceedsThreshold(int threshold, IEnumerable<bool> bools)
        {
           int trueCnt = 0;
           foreach(bool b in bools)
              if (b && (++trueCnt > threshold)) 
                  return true;
           return false;          
        } 
    

    or using LINQ as suggested by other answers:

        public bool ExceedsThreshold(int threshold, IEnumerable<bool> bools)
        { return bools.Count(b => b) > threshold; }
    

    EDIT (to add Joel Coehoorn suggestion: (in .Net 2.x and later)

        public void ExceedsThreshold<T>(int threshold, 
                          Action<T> action, T parameter, 
                          IEnumerable<bool> bools)
        { if (ExceedsThreshold(threshold, bools)) action(parameter); }
    

    or in .Net 3.5 and later:

        public void ExceedsThreshold(int threshold, 
                Action action, IEnumerable<bool> bools)
        { if (ExceedsThreshold(threshold, bools)) action(); }
    

    or as an extension to IEnumerable<bool>

      public static class IEnumerableExtensions
      {
          public static bool ExceedsThreshold<T> 
             (this IEnumerable<bool> bools, int threshold)
          { return bools.Count(b => b) > threshold; }
      }
    

    usage would then be:

      var bools = new [] {true, true, false, false, false, false, true};
      if (bools.ExceedsThreshold(3))
          // code to execute  ...