【问题标题】:Add index position Value of an array of array using Linq使用 Linq 添加数组数组的索引位置值
【发布时间】:2017-07-06 12:32:38
【问题描述】:

我们可以使用arr.Sum() 函数求和。但如果它是一个数组数组。我们将如何添加所有值。 假设数据是 数组/列表是[[1,2,3],[3,4,5],[5,4,3]] 您将如何使用 LINQ 获得 s1 、所有第一个索引值的总和、 s2 、第二个索引值的总和等等。

【问题讨论】:

  • 那么,对于您的具体示例,您希望返回这样的内容吗? [[6]、[12]、[12]]?
  • @Je 不,输出应该是 [ [9], [10], [11]]
  • 每一行的“列”数是否相同?

标签: c# arrays linq


【解决方案1】:

如果你想在 Linq 的帮助下总结 列的值

int[][] source = new int[][] {
  new int[] { 1, 2, 3},
  new int[] { 3, 4, 5},
  new int[] { 5, 4, 3},
};

int maxCol = source.Max(item => item.Length);

var colsSum = Enumerable
  .Range(0, maxCol)
  .Select(index => source.Sum(item => item.Length > index ? item[index] : 0))
  .ToArray(); // let's meaterialize into an array

测试:

Console.Write(string.Join(", ", colsSum));

结果:

 9, 10, 11

总结行的值更容易:

// [6, 12, 12]
var linesSum = source
  .Select(item => item.Sum())
  .ToArray();

如果你想要总计总和:

// 30
var total = source
  .Select(item => item.Sum())
  .Sum();

// 30
var total = source
  .SelectMany(item => item)
  .Sum();

【讨论】:

    【解决方案2】:

    使用AggregateZip 的组合

    var arrays = new[]
    {
        new[] { 1, 2, 3 },
        new[] { 3, 4, 5 },
        new[] { 5, 4, 3 }
    };
    
    var result = 
        arrays.Aggregate(Enumerable.Repeat(0, 3), 
                        (total, array) => total.Zip(array, (sum, current) => sum + current));
    
    // result = { 9, 10, 11 }
    

    Enumerable<T>.Zip 使用相同索引的项目执行提供的函数。

    【讨论】:

    • 如果其中一行的条目数与其他行不同,这会起作用吗?
    • 是的,只有.Zip 函数会计算内部数组,直到到达其中一个数组的末尾。因此,如果最小的数组有 2 个项目,那么它将计算两个项目。 OP没有提到这种限制
    【解决方案3】:

    一种可能的基于 LINQ 的方法(它将处理每行中可变数量的列):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace Test
    {
        public class Program
        {
            private static IEnumerable<int> GetTotalsPerColumn(int[][] inputData)
            {
                var data = inputData.SelectMany(z =>
                {
                    return z.Select((item, index) => new { item, index });
                })
                    .GroupBy(z => z.index)
                    .OrderBy(z => z.Key)
                    .Select(y => y.Select(z => z.item).Sum()
                );
    
                return data;
            }
    
            static void Main(string[] args)
            {
                var inputData = new[] {
                          new[] { 1, 2, 3, 5},
                          new[] { 3, 4, 5, 6},
                          new[] { 5, 4, 3},
                        };
    
                var values = GetTotalsPerColumn(inputData);
    
                foreach (var value in values)
                {
                    Console.WriteLine(value);
                }
    
                Console.ReadLine();
            }
        }
    }
    

    如果您乐于避免使用 LINQ,这是您可以考虑的另一种方法。 GetTotalsPerColumn 填充 Dictionary,其中键是列号,值是总和。

    using System;
    using System.Collections.Generic;
    
    namespace Test
    {
        public class Program
        {
            static void Main(string[] args)
            {
                var inputData = new[] {
                      new[] { 1, 2, 3, 5},
                      new[] { 3, 4, 5, 6},
                      new[] { 5, 4, 3},
                    };
    
                var values = GetTotalsPerColumn(inputData);
    
                foreach (var value in values)
                {
                    Console.WriteLine(value.Key + " - " + value.Value);
                }
    
                Console.ReadLine();
            }
    
            private static Dictionary<int, int> GetTotalsPerColumn(int[][] inputData)
            {
                var values = new Dictionary<int, int>();
    
                foreach (var line in inputData)
                {
                    for (int i = 0; i < line.Length; i++)
                    {
                        int tempValue;
    
                        values.TryGetValue(i, out tempValue);
                        tempValue += line[i];
                        values[i] = tempValue;
                    }
                }
                return values;
            }
        }
    }
    

    【讨论】:

    • 问题是关于使用 LINQ ;)
    • 好点@Fabio - 谢谢。我添加了 LINQ 和非 LINQ 版本。
    • return z.Select(item =&gt; new { item, index = index++ });行中,您不需要自己计算索引。 Select 方法有两个参数项和索引的重载。 - return z.Select((item, index) =&gt; new { item, index});
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-08
    • 2022-12-17
    • 2014-10-17
    相关资源
    最近更新 更多