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));
 }
Beispiel #2
0
        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();
        }