2010-11-15 5 views
4

Pouvez-vous me aider à comprendre,Besoin de précisions sur la fonction Enumerable.Aggregate

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

en bas extrait de code? et ce serait génial si quelqu'un m'expliquait cela en C# 1.1.

(Snippet De 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 

Répondre

6

La Aggregate partie de votre exemple se traduit par quelque chose à peu près comme ceci:

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

La variable workingSentence est un accumulateur qui est mis à jour chaque itération de la boucle en appliquant une fonction à la valeur d'accumulateur existante et à l'élément courant de la séquence; ceci est effectué par le lambda dans votre exemple et par le corps de la boucle foreach dans mon exemple.

+0

Merci et clair pour moi, je vais essayer quelques autres exemples basés sur cela. Merci aussi à Gabe et Will. – paragy

0

C'est assez simple.

string accumulatedText = string.Empty; 
foreach(string part in sentence.Split(' ')) 
    accumulatedText = part + " " + accumulatedText; 

La méthode d'extension LINQ est à peu près équivalent à ceci:

// this method is the lambda 
// (workingSentence, next) => next + " " + workingSentence) 
public string Accumulate(string part, string previousResult) 
{ 
    return part + " " + previousResult; 
} 

public void Reverse(string original) 
{ 
    string retval = string.Empty; 
    foreach(var part in original.Split(' ')) 
    retval = Accumulate(part, retval); 
    return retval; 
} 
2

Bien que LukeH's answer est plus facile à comprendre, je pense que cela est une approximation plus proche de la traduction C# 1.0 de l'appel de fonction Aggregate.

(workingSentence, next) => + next + " " + workingSentence est un lambda, ce qui signifie délégué sans nom. Afin de le traduire, nous devons créer un type de délégué qui le décrit (je l'appelle StringAggregateDelegate) et ensuite faire la fonction elle-même (je l'appelle AggregateDelegate). La fonction Aggregate elle-même obtient le premier élément de sa source, puis boucle sur les éléments restants et appelle le délégué avec le résultat accumulé et l'élément suivant.

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)); 
Questions connexes