Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need more details on Enumerable.Aggregate function

Can you help me to understand,

       words.Aggregate((workingSentence, next) => + next + " " + workingSentence);   

from below code snippet? and it would be great if someone explain me to achive this in C# 1.1.

(Snippet From MS)-

        string sentence = "the quick brown fox jumps over the lazy dog";
        // Split the string into individual words.
        string[] words = sentence.Split(' ');
        // Prepend each word to the beginning of the 
        // new sentence to reverse the word order.
        string reversed = words.Aggregate((workingSentence, next) =>
                                              next + " " + workingSentence);
        Console.WriteLine(reversed);
        // This code produces the following output:
        //
        // dog lazy the over jumps fox brown quick the
like image 546
indiPy Avatar asked Nov 15 '10 13:11

indiPy


2 Answers

The Aggregate part of your example translates to something roughly like this:

string workingSentence = null;
bool firstElement = true;
foreach (string next in words)
{
    if (firstElement)
    {
        workingSentence = next;
        firstElement = false;
    }
    else
    {
        workingSentence = next + " " + workingSentence;
    }
}
string reversed = workingSentence;

The workingSentence variable is an accumulator that is updated on each iteration of the loop by applying a function to the existing accumulator value and the current element of the sequence; this is performed by the lambda in your example and by the body of the foreach loop in my example.

like image 193
LukeH Avatar answered Sep 22 '22 10:09

LukeH


Although LukeH's answer is easier to understand, I think this is a closer approximation of the C# 1.0 translation of the Aggregate function call.

(workingSentence, next) => + next + " " + workingSentence is a lambda, which means unnamed delegate. In order to translate it we have to create a delegate type that describes it (I call it StringAggregateDelegate) and then make the function itself (I call it AggregateDelegate). The Aggregate function itself gets the first element of its source, then loops over the remaining elements and calls the delegate with the accumulated result and the next element.

delegate string StringAggregateDelegate(string, string);

static string AggregateDelegate(string workingSentence, string next)
{
    return next + " " + workingSentence;
}

static string Aggregate(IEnumerable source,
                        StringAggregateDeletate AggregateDelegate)
{
    // start enumerating the source;
    IEnumerator e = source.GetEnumerator();
    // return empty string if the source is empty
    if (!e.MoveNext())
        return "";
    // get first element as our base case
    string workingSentence = (string)e.Current;
    // call delegate on each item after the first one
    while (e.MoveNext())
        workingSentence = AggregateDelegate(workingSentence, (string)e.Current);
    // return the result
    return workingSentence;
}

// now use the Aggregate function:
    string[] words = sentence.Split(' ');
    // Prepend each word to the beginning of the
    // new sentence to reverse the word order.
    string reversed = Aggregate(words,
                                new StringAggregateDelegate(AggregateDelegate));
like image 26
Gabe Avatar answered Sep 22 '22 10:09

Gabe