// 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];
}
}
}