private static IEnumerable <double> ToNumbers(ValueDescriptor descriptor, CultureInfo culture, IEnumerable <object> values) { return(values .Select(x => ValueConversions.ToNumber(descriptor, culture, x)) .Where(x => x.HasValue) .Select(x => x.Value)); }
private object Aggregate(DataSet dataset, ValueDescriptor descriptor, IEnumerable <object> values) { Debug.Assert(descriptor != null); Debug.Assert(values != null); Debug.Assert(_accumulator.IsEmpty || _culture != null); if (!String.IsNullOrWhiteSpace(descriptor.AggregationExpression)) { var evaluator = new ExpressionEvaluator(dataset); evaluator.AddConstant(ExpressionEvaluator.IdentifierValues, values); return(evaluator.Evaluate(() => descriptor.AggregationExpression)); } // TODO: AggregationMode.None may be checked at the very beginning, no need to create a // list of values if there is nothing to do with them... if (descriptor.PreferredAggregation == AggregationMode.None) { return(null); } if (descriptor.PreferredAggregation == AggregationMode.Count) { return(values.Count()); } var numbers = values .Select(x => ValueConversions.ToNumber(descriptor, _culture, x)) .Where(x => x.HasValue); // Sum of an empty set is zero but average is null if (descriptor.PreferredAggregation == AggregationMode.Sum) { return(numbers.Sum()); } if (descriptor.PreferredAggregation == AggregationMode.Average) { return(numbers.Any() ? (object)(numbers.Sum() / numbers.Count()) : null); } throw new NotSupportedException(); }