Elegantly determine if more than one boolean is “true”

前端 未结 22 1030
深忆病人
深忆病人 2020-12-04 13:40

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

相关标签:
22条回答
  • 2020-12-04 14:42

    In most languages true is equivalent to a non-zero value while false is zero. I don't have exact syntax for you, but in pseudo code, what about:

    if ((bool1 * 1) + (bool2 * 1) + (bool3 * 1) > 2)
    {
        //statements here
    }
    
    0 讨论(0)
  • 2020-12-04 14:44

    If you only have five different values, you can easily do the test by packing the bits in to a short or an int and checking to see if it is any of the zero or one bit answers. The only invalid numbers you could get would be..

    0x 0000 0000 
    0x 0000 0001
    0x 0000 0010
    0x 0000 0100
    0x 0000 1000
    0x 0001 0000
    

    This gives you six values to search for, put them in a lookup table and if it's not in there, you have your answer.

    This gives you a simple answer.

       public static boolean moreThan1BitSet(int b)
       {
          final short multiBitLookup[] = { 
                1, 1, 1, 0, 1, 0, 0, 0,
                1, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0,
                1, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0
          };
          if(multiBitLookup[b] == 1)
             return false;
          return true;
       }
    

    This doesn't scale well past 8 bits, but you only have five.

    0 讨论(0)
  • 2020-12-04 14:45

    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  ...
    
    0 讨论(0)
  • 2020-12-04 14:45

    I was recently having this same issue, where I had three boolean values, which I needed to check that only 1 of them was true at a time. For this I used the xor operator as follows:

    bool a = true;
    bool b = true;
    bool c = false;
    
    if (a || b || c)
    {
        if (a ^ b ^ c){
            //Throw Error
        }
    }
    

    This code will throw an error as a and b are both true.

    For reference: http://www.dotnetperls.com/xor

    I have only just found the xor operator in C# if anyone knows of any pit falls of this strategy, please let me know.

    0 讨论(0)
提交回复
热议问题