private static object SumIf(List <Expression> p) { // get parameters var range = p[0] as IEnumerable; // range of values to match the criteria against var sumRange = p.Count < 3 ? p[0] as XObjectExpression : p[2] as XObjectExpression; // range of values to sum up var criteria = p[1].Evaluate(); // the criteria to evaluate var rangeValues = range.Cast <object>().ToList(); var sumRangeValues = sumRange.Cast <object>().ToList(); // compute total var ce = new CalcEngine(); var tally = new Tally(); for (var i = 0; i < Math.Max(rangeValues.Count, sumRangeValues.Count); i++) { var targetValue = i < rangeValues.Count ? rangeValues[i] : string.Empty; if (CalcEngineHelpers.ValueSatisfiesCriteria(targetValue, criteria, ce)) { var value = i < sumRangeValues.Count ? sumRangeValues[i] : 0d; tally.AddValue(value); } } // done return(tally.Sum()); }
private static object SumIfs(List <Expression> p) { // get parameters var sumRange = p[0] as IEnumerable; var sumRangeValues = new List <object>(); foreach (var value in sumRange) { sumRangeValues.Add(value); } var ce = new CalcEngine(); var tally = new Tally(); int numberOfCriteria = p.Count / 2; // int division returns floor() automatically, that's what we want. // prepare criteria-parameters: var criteriaRanges = new Tuple <object, List <object> > [numberOfCriteria]; for (int criteriaPair = 0; criteriaPair < numberOfCriteria; criteriaPair++) { var criterion = p[criteriaPair * 2 + 1].Evaluate(); var criteriaRange = p[(criteriaPair + 1) * 2] as IEnumerable; var criteriaRangeValues = new List <object>(); foreach (var value in criteriaRange) { criteriaRangeValues.Add(value); } criteriaRanges[criteriaPair] = new Tuple <object, List <object> >( criterion, criteriaRangeValues); } for (var i = 0; i < sumRangeValues.Count; i++) { bool shouldUseValue = true; foreach (var criteriaPair in criteriaRanges) { if (!CalcEngineHelpers.ValueSatisfiesCriteria( criteriaPair.Item2[i], criteriaPair.Item1, ce)) { shouldUseValue = false; break; // we're done with the inner loop as we can't ever get true again. } } if (shouldUseValue) { tally.AddValue(sumRangeValues[i]); } } // done return(tally.Sum()); }
private static object SumIf(List <Expression> p) { // get parameters var range = p[0] as IEnumerable; var sumRange = p.Count < 3 ? range : p[2] as IEnumerable; var criteria = p[1].Evaluate(); // build list of values in range and sumRange var rangeValues = new List <object>(); foreach (var value in range) { rangeValues.Add(value); } var sumRangeValues = new List <object>(); foreach (var value in sumRange) { sumRangeValues.Add(value); } // compute total var ce = new CalcEngine(); var tally = new Tally(); for (var i = 0; i < Math.Min(rangeValues.Count, sumRangeValues.Count); i++) { if (ValueSatisfiesCriteria(rangeValues[i], criteria, ce)) { tally.AddValue(sumRangeValues[i]); } } // done return(tally.Sum()); }