2017-07-06 11 views
1

arr.Sum()関数を使用して合計を計算できます。しかし、それが配列の配列の場合。どのようにすべての値を追加しますか? データが であると仮定します。配列/リストは[[1,2,3],[3,4,5],[5,4,3]] どのようにして、すべての最初のインデックス値の合計、s2、2番目のインデックス値の合計などをLINQを使用して取得しますか?インデックス位置を追加するLinqを使用して配列の配列の値

+0

したがって、具体的な例として、このようなものを返すことを望んでいますか? [[6]、[12]、[12]]? –

+0

@Jeいいえ、出力は[[9]、[10]、[11]]である必要があります –

+0

各行の列の数は同じですか? – mjwills

答えて

6

あなたはの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 

は総括lin ESの価値観はあるが容易:

// [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(); 
0

使用Aggregateの組み合わせとZip

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は、同じインデックスのアイテムで提供された機能を実行します。 (各行の列の可変数を処理します)

+0

行の1つが他の行と異なる数のエントリを持つ場合、これは機能しますか? – mjwills

+0

そうですが、 '.Zip'関数だけが内部配列を計算し、それらのうちの1つの終わりに達するまで行います。したがって、最小配列に2つの項目がある場合は、2つの項目を計算します。 OPはこの種の制限については言及していません – Fabio

0

可能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; 
     } 
    } 
} 
+0

LINQ_についての質問でした;) – Fabio

+0

良い点@ファビオ - ありがとう。私はLINQと非LINQの両方のバージョンを追加しました。 – mjwills

+0

'return z.Select(item => new {item、index = index ++});'あなた自身のインデックスを計算する必要はありません。 'Select'メソッドは、itemとindexという2つの引数でオーバーロードします。 - 'return z.Select((item、index)=> new {item、index}); ' – Fabio

関連する問題