Esempio n. 1
0
        /// <summary>
        /// Computes the mean average of the sequence of values that are
        /// obtained by invoking a transform function on each element of the input sequence.
        /// </summary>
        /// <remarks>The values returned by the transform function must support the Add and Divide(Int32) operators</remarks>
        public static TValue Average <TSource, TValue>(this IEnumerable <TSource> source, Func <TSource, TValue> selector)
        {
            source.ThrowIfNull("source");
            selector.ThrowIfNull("selector");
            int    count = 0;
            TValue sum   = Operator <TValue> .Zero; // not the same as default(T); think "int?"

            foreach (TSource item in source)
            {
                if (Operator.AddIfNotNull(ref sum, selector(item)))
                {
                    count++;
                }
            }
            if (count == 0)
            {
                sum = default(TValue);
                if (sum != null)
                {
                    throw new InvalidOperationException("Cannot perform non-nullable average over an empty series");
                }
                return(sum);
            }
            else
            {
                return(Operator.DivideInt32(sum, count));
            }
        }
        /// <summary>
        /// Returns a future to the average of a sequence of values that are
        /// obtained by taking a transform of the input sequence
        /// </summary>
        /// <remarks>Null values are removed from the average</remarks>
        public static IFuture <TResult> Average <TSource, TResult>(this IDataProducer <TSource> source, Func <TSource, TResult> selector)
        {
            source.ThrowIfNull("source");
            selector.ThrowIfNull("selector");

            Future <TResult> ret = new Future <TResult>();
            TResult          sum = Operator <TResult> .Zero;
            int count            = 0;  // should this be long? Would demand a Operator.DivideInt64

            source.DataProduced += item => {
                if (Operator.AddIfNotNull(ref sum, selector(item)))
                {
                    count++;
                }
            };
            source.EndOfData += () => {
                if (count == 0)
                {
                    // check if Nullable<T> by seeing if default(T) is
                    // nullable; if so, return null; otherwise, throw
                    sum = default(TResult);
                    if (sum != null)
                    {
                        throw new InvalidOperationException("Cannot perform non-nullable average over an empty series");
                    }
                    ret.Value = sum;                     // null
                }
                else
                {
                    ret.Value = Operator.DivideInt32(sum, count);
                }
            };
            return(ret);
        }
Esempio n. 3
0
        /// <summary>
        /// Computes the sum of the sequence of values that are
        /// obtained by invoking a transform function on each element of the input sequence.
        /// </summary>
        /// <remarks>The values returned by the transform function must support the Add operator</remarks>
        public static TValue Sum <TSource, TValue>(this IEnumerable <TSource> source, Func <TSource, TValue> selector)
        {
            source.ThrowIfNull("source");
            selector.ThrowIfNull("selector");
            TValue sum = Operator <TValue> .Zero; // not the same as default(T); think "int?"

            foreach (TSource item in source)
            {
                Operator.AddIfNotNull(ref sum, selector(item));
            }
            return(sum);
        }
        /// <summary>
        /// Returns a future to the sum of a sequence of values that are
        /// obtained by taking a transform of the input sequence
        /// </summary>
        /// <remarks>Null values are removed from the sum</remarks>
        public static IFuture <TResult> Sum <TSource, TResult>(this IDataProducer <TSource> source, Func <TSource, TResult> selector)
        {
            source.ThrowIfNull("source");
            selector.ThrowIfNull("selector");

            Future <TResult> ret = new Future <TResult>();
            TResult          sum = Operator <TResult> .Zero;

            source.DataProduced += item => {
                Operator.AddIfNotNull(ref sum, selector(item));
            };
            source.EndOfData += () => ret.Value = sum;
            return(ret);
        }