C#语言的linq有类似于SummaryStatistics的功能吗?

4
在Java中,我可以这样做:
List<String> stringList = getRandomStrings(100_000, 1000);
IntSummaryStatistics stats =
                stringList.stream()
                        .filter(Objects::nonNull)
                        .mapToInt(String::length)
                        .summaryStatistics();

System.out.println(stats);

输出结果为:
IntSummaryStatistics{count=100000, sum=49868013, min=0, average=498.680130, max=999}

linq有相同的功能吗?还是我必须分别计算所有内容?

Java可以一次完成,看起来在C#中您必须分别计算所有内容Average(), Count(), Sum(), Min()Max()


3
Java中的summaryStatistics是一个收集统计数据的内置类。它可以使用不同的方法来计算元素数量、总和、平均值、最大值和最小值等统计信息,并将结果存储在一个对象中。这个对象可以用于进一步处理或打印出结果。 - Eldho
不,至少我认为LINQ不会提供这样的输出。你可以使用类似于汇总统计的方法来实现。 - Eldho
你如何对字符串进行求和和平均? - juharr
@juharr 是的,但那不是重点。 - Coder-Man
1
@Coder-Man 写一个简单的循环来计算所有这些值也是非常微不足道的。为什么Java要用这种东西来垃圾化他们的代码库,这超出了我的理解范围。 - juharr
显示剩余6条评论
1个回答

13

我不知道.NET内置了任何相当功能的内容,但是您可以使用LINQ中的Aggregate轻松实现它。 这满足您仅枚举源集合一次的要求。

var ints = new List<int>() { 1, 2, 3, 4, 677, 8 };

var summary = ints.Aggregate(
    seed: (
        count: 0, 
        sum: 0, 
        min: int.MaxValue, 
        max: int.MinValue),
    func: (acc, x) => (
        count: acc.count + 1, 
        sum: acc.sum + x, 
        min: Math.Min(acc.min, x), 
        max: Math.Max(acc.max, x)),
    resultSelector: acc => (
        acc.count, 
        acc.sum, 
        acc.min, 
        acc.max, 
        avg: (double)acc.sum / acc.count));

Console.WriteLine(
    $"count = {summary.count}, " +
    $"sum = {summary.sum}, " +
    $"min = {summary.min}, " +
    $"max = {summary.max}, " +
    $"average = {summary.avg}");

如果你的集合非常大,并且想要并行处理它,可以使用以下重载:

var summary = ints.AsParallel().Aggregate(
    seed: (
        count: 0,
        sum: 0,
        min: int.MaxValue,
        max: int.MinValue),
    updateAccumulatorFunc: (acc, x) => (
        count: acc.count + 1,
        sum: acc.sum + x,
        min: Math.Min(acc.min, x),
        max: Math.Max(acc.max, x)),
    combineAccumulatorsFunc: (acc1, acc2) => (
        count: acc1.count + acc2.count,
        sum: acc1.sum + acc2.sum,
        min: Math.Min(acc1.min, acc2.min),
        max: Math.Max(acc1.max, acc2.max)),
    resultSelector: acc => (
        acc.count,
        acc.sum,
        acc.min,
        acc.max,
        avg: (double)acc.sum / acc.count));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接