需要有关Enumerable.Aggregate函数的更多细节

时间:2010-11-15 13:12:55

标签: c# aggregate-functions

你能帮我理解吗,

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

从下面的代码段?如果有人解释我在C#1.1中实现这一点,那就太好了。

(来自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

3 个答案:

答案 0 :(得分:6)

您的示例中的Aggregate部分会转换为大致相同的内容:

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

workingSentence变量是累加器,它通过将函数应用于现有累加器值和序列的当前元素,在循环的每次迭代中更新;这是由示例中的lambda和我示例中foreach循环的主体执行的。

答案 1 :(得分:2)

虽然LukeH's answer更容易理解,但我认为这是Aggregate函数调用的C#1.0转换的更接近的近似值。

(workingSentence, next) => + next + " " + workingSentence是一个lambda,意思是未命名的委托。为了翻译它,我们必须创建一个描述它的委托类型(我称之为StringAggregateDelegate),然后自己创建函数(我称之为AggregateDelegate)。 Aggregate函数本身获取其源的第一个元素,然后遍历其余元素并使用累积结果和下一个元素调用委托。

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

答案 2 :(得分:0)

非常简单。

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

linq扩展方法大致相当于:

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