0Pricing
C# Academy · レッスン

集計とToList

CountやSumを使い、リストとして具体化します。

「集計とToList」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。

要素を数える

Countは、シーケンス内の要素数を返します。述語を指定すると、条件に一致する要素だけを数えます。

これは列挙を強制するため、合計を生成するまでシーケンス全体を走査します。集計操作の一種です。

using System;
using System.Linq;

int[] nums = { 1, 2, 3, 4, 5 };
Console.WriteLine(nums.Count());
Console.WriteLine(nums.Count(n => n > 2));

値を合計する

Sumは数値を加算します。数値シーケンスに対して使用すると要素を合計し、セレクターを指定すると各要素から射影した値を合計します。

戻り値は、元のシーケンスまたはセレクターの結果と同じ数値型になります。

using System;
using System.Linq;
using System.Collections.Generic;

record Order(int Qty, decimal Price);
var orders = new List<Order> { new(2, 5m), new(3, 4m) };
decimal total = orders.Sum(o => o.Qty * o.Price);
Console.WriteLine(total);

値の平均を求める

Averageは算術平均を計算します。Sumと同様に、オプションのセレクターを指定できます。

元のシーケンスが整数であっても、結果は浮動小数点型(たとえばdouble)になります。これにより、除算で精度が失われることを防げます。

using System;
using System.Linq;

int[] scores = { 80, 90, 100 };
double avg = scores.Average();
Console.WriteLine(avg);

最小値と最大値

MinとMaxは、最小値と最大値を返します。セレクターを指定すると、射影されたキーを対象に集計します。

最新の.NETでは、MaxByとMinByを使うと、キーの値だけでなく、極端なキーを持つ要素全体が返されます。

using System;
using System.Linq;
using System.Collections.Generic;

record P(string Name, int Age);
var ps = new List<P> { new("Ana", 30), new("Bo", 22) };
var oldest = ps.MaxBy(p => p.Age);
Console.WriteLine(oldest!.Name);

空のシーケンスに関する注意点

空のシーケンスに対して値型のAverage、Min、Maxを使用すると、InvalidOperationExceptionがスローされます。Sumは0を返し、Countも0を返します。

空になる可能性があるデータの平均を求める前に、Any()で確認するか、DefaultIfEmptyを使用してください。

using System;
using System.Linq;

int[] empty = Array.Empty<int>();
double avg = empty.DefaultIfEmpty(0).Average();
Console.WriteLine(avg);

独自の畳み込みにAggregateを使う

Aggregateは、アキュムレーター関数を使ってシーケンスを1つの値に畳み込みます。これはSumなどの背後にある一般的な形式です。

初期値を指定し、各要素を実行中の結果に結合できます。積や連結、独自の処理などに便利です。

using System;
using System.Linq;

int[] nums = { 1, 2, 3, 4 };
int product = nums.Aggregate(1, (acc, n) => acc * n);
Console.WriteLine(product);

ToListでマテリアライズする

ToListはクエリをすぐに実行し、結果をList<T>にコピーします。これにより、意図的に遅延実行を終了させます。

安定したスナップショットを取得したい場合、高コストなパイプラインの再実行を避けたい場合、インデックスやCountプロパティなど、リストの機能を使いたい場合に使用します。

using System;
using System.Linq;

int[] nums = { 1, 2, 3, 4 };
var evens = nums.Where(n => n % 2 == 0).ToList();
evens.Add(6);
Console.WriteLine(string.Join(", ", evens));

ToArrayとToDictionary

関連するマテリアライザーには、固定サイズの配列を作成するToArrayと、キーによる検索を行うToDictionaryがあります。

ToDictionaryはキーセレクター(およびオプションの値セレクター)を受け取り、2つの要素が同じキーを生成するとスローします。

using System;
using System.Linq;
using System.Collections.Generic;

record P(string Name, int Age);
var ps = new List<P> { new("Ana", 30), new("Bo", 22) };
var byName = ps.ToDictionary(p => p.Name, p => p.Age);
Console.WriteLine(byName["Ana"]);

マテリアライズする理由

遅延実行されるクエリは、反復処理されるたびに再実行されます。パイプラインのコストが高い場合や、変化するデータ元を読み取る場合、この繰り返しによってバグや速度低下が発生します。

ToListを1回呼び出すと結果が取得されるため、その後の読み取りは低コストで一貫したものになります。

using System;
using System.Linq;

int runs = 0;
int[] nums = { 1, 2, 3 };
var list = nums.Select(n => { runs++; return n; }).ToList();
foreach (var _ in list) { }
foreach (var _ in list) { }
Console.WriteLine(runs);

First、Single、Any

要素演算子も実行を強制します。Firstは最初に一致する要素を返し、一致する要素がなければスローします。FirstOrDefaultは代わりに既定値を返し、Singleは要素がちょうど1つであることを要求します。

Anyは、すべての要素を数え上げることなく、シーケンスに一致する要素があるかどうかを示します。

using System;
using System.Linq;

int[] nums = { 3, 8, 5, 12 };
int firstBig = nums.First(n => n > 7);
bool hasOdd = nums.Any(n => n % 2 == 1);
Console.WriteLine($"{firstBig} {hasOdd}");

完全なパイプライン

実際のクエリでは、フィルタリング、射影、並べ替え、集計をつなげ、最後にマテライザーを置くことがよくあります。

上から下へ、フィルター、形の整形、順序付け、収集という順に読みます。最後のToListによって、パイプライン全体が1回実行されます。

using System;
using System.Linq;
using System.Collections.Generic;

record Sale(string City, int Amt);
var sales = new List<Sale> { new("NY", 5), new("LA", 3), new("NY", 9) };
var top = sales.Where(s => s.Amt > 4)
               .OrderByDescending(s => s.Amt)
               .Select(s => s.City)
               .ToList();
Console.WriteLine(string.Join(", ", top));

確認してみましょう

遅延実行とマテリアライズについて考えてみましょう。

まとめ

集計演算子はシーケンスを1つの値に縮約します。Count、Sum、Average、Min/Max、MinBy/MaxBy、そして汎用的なAggregateがあります。これらは実行を強制し、空の入力元に対してはスローすることがあります。

ToList、ToArray、ToDictionaryは結果をマテリアライズし、遅延実行を終了させます。そのため、高コストなパイプラインを1回だけ実行できます。これで、LINQのフィルタリングと射影に関するツールキットは完了です。

よくある質問

「集計とToList」レッスンは無料ですか?

はい。「集計とToList」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。

「集計とToList」で何を学びますか?

CountやSumを使い、リストとして具体化します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C# Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「集計とToList」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC# Academyレッスンでコードを書いて実行できますか?

はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Whereとフィルタリング
  2. SelectとProjection
  3. OrderByとグループ化
  4. 集計とToList
← C# Academyに戻る