locked
Converting a boolean expression from a string to a boolean RRS feed

  • Question

  • Can someone help me figure out how to simplify the following code?  There is a lot of repetitive coding (a capital sin), and essentially the string parameter "<", "<=", etc. that is passed is the same as the boolean comparison that is done in each case statement. 

    public static double SumIf(VariableList<Output> _array, string _comparisonOperator, int _compareValue)
    {
      double sum = 0;
      switch (_comparisonOperator)
      {
        case "<" :
          {
            for (int i = 0; i.CompareTo(_compareValue) < 0; i++)
            {
              sum += _array[i].value;
            }
            break;
          }
        case "<=" :
          {
            for (int i = 0; i.CompareTo(_compareValue) <= 0; i++)
            {
              sum += _array[i].value;
            }
            break;
          }
        case "=":
          {
            for (int i = 0; i.CompareTo(_compareValue) = 0; i++)
            {
              sum += _array[i].value;
            }
            break;
          }
        case ">=" :
          {
            for (int i = _array.count; i.CompareTo(_compareValue) >= 0; i--)
            {
              sum += _array[i].value;
            }
            break;
          }
        case ">" :
          {
            for (int i = _array.count; i.CompareTo(_compareValue) > 0; i--)
            {
              sum += _array[i].value;
            }
            break;
          }
        default :
          throw new ArgumentException ("\"{0}\" is an invalid comparison type", _comparisonOperator);
      }
      return(sum);
    }
    
    

     Thanks.

    Tuesday, September 21, 2010 2:12 AM

Answers

  • You can define a delegate with just the comparison:

    public static double SumIf(VariableList<Output> _array, string _comparisonOperator, int _compareValue)
    {
     double sum = 0;
     Func<int, int, bool> compare;
     int inc = 1;
     int start = 0;
     switch (_comparisonOperator)
     {
      case "<":
       compare = (a, b) => a < b;
       break;
      case "<=":
       compare = (a, b) => a <= b;
       break;
      case "=":
       compare = (a, b) => a == b;
       break;
      case ">":
       compare = (a, b) => a > b;
       inc = -1;
       start = _array.count;
       break;
      case ">=":
       compare = (a, b) => a >= b;
       inc = -1;
       start = _array.count;
       break;
      default:
       throw new ArgumentException("\"{0}\" is an invalid comparison type", _comparisonOperator);
     }
     for (int i = start; compare(i, _compareValue); i += inc)
     {
      sum += _array[i].value;
     }
     return sum;
    }
    
    • Marked as answer by Evan Ermes Tuesday, September 21, 2010 11:23 AM
    • Edited by Louis.fr Tuesday, September 21, 2010 12:38 PM Included the start variable, as indicated by Evan
    Tuesday, September 21, 2010 10:20 AM

All replies

  • public
     static
     double
     SumIf(VariableList<Output> _array, string
     _comparisonOperator, int
     _compareValue)
    {
     double
     sum = 0;
     switch
     (_comparisonOperator)
     {
      case
     "<"
     :
     case "<=" :
     case "=" :
     case ">=" :
     case ">" :
     for (int i = _array.count; i.CompareTo(_compareValue) > 0; i--) { sum += _array[i].value; } break ;

      default : throw new ArgumentException ("\"{0}\" is an invalid comparison type" , _comparisonOperator); } return (sum); }


    You can use multiple cases but you cannot fall through from one case to another like C.

    case "one":
        DoSomething();
    case "Two":
        MoreSomething();

    You also do not need the braces around each case statement.

    Ta Ken
    Tuesday, September 21, 2010 3:03 AM
  • Thank you Ta Ken.  However, I do not quite understand your proposed solution.  It seems like ALL of the cases would result in a single boolean expression:  i.CompareTo(_compareValue) < 0. 

     

    However, in my original code, each case corresponded to a different boolean expression (i.e. ">=" corresponded to  i.CompareTo(_compareValue) >= 0

    Tuesday, September 21, 2010 3:18 AM
  • You can define a delegate with just the comparison:

    public static double SumIf(VariableList<Output> _array, string _comparisonOperator, int _compareValue)
    {
     double sum = 0;
     Func<int, int, bool> compare;
     int inc = 1;
     int start = 0;
     switch (_comparisonOperator)
     {
      case "<":
       compare = (a, b) => a < b;
       break;
      case "<=":
       compare = (a, b) => a <= b;
       break;
      case "=":
       compare = (a, b) => a == b;
       break;
      case ">":
       compare = (a, b) => a > b;
       inc = -1;
       start = _array.count;
       break;
      case ">=":
       compare = (a, b) => a >= b;
       inc = -1;
       start = _array.count;
       break;
      default:
       throw new ArgumentException("\"{0}\" is an invalid comparison type", _comparisonOperator);
     }
     for (int i = start; compare(i, _compareValue); i += inc)
     {
      sum += _array[i].value;
     }
     return sum;
    }
    
    • Marked as answer by Evan Ermes Tuesday, September 21, 2010 11:23 AM
    • Edited by Louis.fr Tuesday, September 21, 2010 12:38 PM Included the start variable, as indicated by Evan
    Tuesday, September 21, 2010 10:20 AM
  • Thanks, Louis--I like that! That's a great solution!

    I think I also need a startCtr = 0, which in the last two cases is changed to startCtr = _array.Count.  Then the for..next loop would be for (int i = startCtr; ...)

     

    Tuesday, September 21, 2010 11:22 AM