// Copyright (c) Microsoft. All rights reserved. using System; using System.Collections.Generic; using System.Linq; namespace Microsoft.Agents.AI.Workflows; /// /// Provides a set of streaming aggregation functions for processing sequences of input values in a stateful, /// incremental manner. /// public static class StreamingAggregators { /// /// Creates a streaming aggregator that returns the result of applying the specified conversion function to the /// first input value. /// /// Subsequent inputs after the first are ignored by the aggregator. This method is useful for /// scenarios where only the first occurrence in a stream is relevant. The conversion function is invoked at most /// once. /// The type of the input elements to be aggregated. /// The type of the result produced by the conversion function. /// A function that converts an input value of type to a result /// of type . This function is applied to the first input received. /// An aggregation function that yields the result of converting the first input using the specified function. public static Func First(Func conversion) { return Aggregate; TResult? Aggregate(TResult? runningResult, TInput input) { runningResult ??= conversion(input); return runningResult; } } /// /// Creates a streaming aggregator that returns the first input element. /// /// The type of the input elements to aggregate. /// A an aggrgation function that yields the first input element. public static Func First() => First(input => input); /// /// Creates a streaming aggregator that returns the result of applying the specified conversion to the most recent /// input value. /// /// The type of the input elements to be aggregated. /// The type of the result produced by the conversion function. /// A function that converts each input value to a result. Cannot be null. /// A aggregator function that yields the result of converting the last input received using the specified /// function. public static Func Last(Func conversion) { return Aggregate; TResult? Aggregate(TResult? runningResult, TInput input) { return conversion(input); } } /// /// Creates a streaming aggregator that returns the last element in a sequence. /// /// The type of elements in the input sequence. /// An aggregator function that yields the last element of the input. public static Func Last() => Last(input => input); /// /// Creates a streaming aggregator that produces the union of results by applying a conversion function to each /// input and accumulating the results. /// /// The type of the input elements to be aggregated. /// The type of the result elements produced by the conversion function. /// A function that converts each input element to a result element to be included in the union. /// An aggregator function that, for each input, returns an enumerable containing the result of converting every /// element produced so far. public static Func?, TInput, IEnumerable?> Union(Func conversion) { return Aggregate; IEnumerable Aggregate(IEnumerable? runningResult, TInput input) { return runningResult is not null ? runningResult.Append(conversion(input)) : [conversion(input)]; } } /// /// Creates a streaming aggregator that produces the union of all input sequences of type TInput. /// /// The resulting aggregator combines all input sequences into a single sequence containing /// distinct elements. The order of elements in the output sequence is not guaranteed. /// The type of the elements in the input sequences to be aggregated. /// An aggregator function, that, when applied to multiple input sequences, returns an /// containing the union of all elements from those sequences. public static Func?, TInput, IEnumerable?> Union() { return Aggregate; static IEnumerable Aggregate(IEnumerable? runningResult, TInput input) { return runningResult is not null ? runningResult.Append(input) : [input]; } } }