我试图想出一个linq查询来转换IEnumerable<int>为另一个IEnumerable<int>,其中结果中的每个int是从初始列表到该位置的所有int的总和:
鉴于int[] a
我需要int[] b
Where b[0] = a[0], b[1] = a[0] + a[1], b[2] = a[0] + a[1] + a[2]等等
或者,上面的总和可以写成b[1] = b[0] + a[1], b[2] = b[1] + a[2]等等,但我不知道这会有什么帮助.
当然,我可以通过for循环执行此操作,但是我从查询中获取a []序列,并且我认为如果我继续查询而不是突然添加for那里它会更好看:)
Jon*_*eet 16
好吧,你可以很容易地做副作用,虽然它很icky ......
int sum = 0;
int[] b = a.Select(x => (sum += x)).ToArray();
Run Code Online (Sandbox Code Playgroud)
如果框架提供了一种"运行聚合"来封装它,那将是很好的,但它并不是我所知道的.
我刚才写了一个函数来做这个.它类似于Haskell的scanl函数.
public static IEnumerable<TResult> Scan<T, TResult>(
this IEnumerable<T> source,
Func<T, T, TResult> combine)
{
using (IEnumerator<T> data = source.GetEnumerator())
if (data.MoveNext())
{
T first = data.Current;
yield return first;
while (data.MoveNext())
{
first = combine(first, data.Current);
yield return first;
}
}
}
int[] b = a
.Scan((running, current) => running + current)
.ToArray();
Run Code Online (Sandbox Code Playgroud)
Skeet先生解决方案的替代方案:如果我们放弃了对linq查询的要求,并且更确切地说"转换IEnumerable<int>为另一个IEnumerable<int>",我们可以使用:
static IEnumerable<int> Sum(IEnumerable<int> a)
{
int sum = 0;
foreach (int i in a)
{
sum += i;
yield return sum;
}
}
Run Code Online (Sandbox Code Playgroud)
我们可以应用于无限系列:
foreach (int i in Sum(MyMath.NaturalNumbers))
Console.WriteLine(i);
Run Code Online (Sandbox Code Playgroud)
如果您不想一次创建整个数组,这也很有用.
| 归档时间: |
|
| 查看次数: |
3487 次 |
| 最近记录: |