2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【C#】GroupBy()の使い方

Last updated at Posted at 2022-03-10

なりゆき

個人的にこのGroupBy()を何回か使ったことがあるのですが、戻り値の型がわかりづらく理解できていないためこの記事にまとめることにしました。理解する時に作成した図も貼り付けておきます。分かりづらかったらすみません。
image.png

基本の使い方

下記のソース例ではグループ化するプロパティにCountryNameを選択しています。

GroupByを使ってグループ化するソース例
List<City> cityList = new List<City>();

cityList.Add(new City { CountryName = "日本", CityName = "東京" });
cityList.Add(new City { CountryName = "日本", CityName = "大阪" });
cityList.Add(new City { CountryName = "アメリカ", CityName = "ロサンゼルス" });
cityList.Add(new City { CountryName = "アメリカ", CityName = "シアトル" });

//国名をグループ化するプロパティとして選択してグループ化する。
var groupByCountryName = cityList.GroupBy(x => x.CountryName);

class City
{
    public string CountryName { get; set; } = "";
    public string CityName { get; set; } = "";
}

グループ化した値の取得は下記のようにします。

グループ化した値を取得するソース例
List<City> cityList = new List<City>();

cityList.Add(new City { CountryName = "日本", CityName = "東京" });
cityList.Add(new City { CountryName = "日本", CityName = "大阪" });
cityList.Add(new City { CountryName = "アメリカ", CityName = "ロサンゼルス" });
cityList.Add(new City { CountryName = "アメリカ", CityName = "シアトル" });

//国名をグループ化するプロパティとして選択してグループ化する。
var groupByCountryName = cityList.GroupBy(x => x.CountryName);

foreach (var groupingCity in groupByCountryName)
{
    //Keyの中身はGroupByでグループ化したプロパティです。
    //この例では[CountryName]プロパティが値として取得できます。
    Console.WriteLine($"Key:{groupingCity.Key}");

    foreach (var city in groupingCity)
    {
        //グループ化した結果を列挙しています。
        Console.WriteLine($"国名:{city.CountryName}、都市名:{city.CityName}");
    }

    //出力
    //Key:日本
    //国名:日本、都市名:東京
    //国名:日本、都市名:大阪
    //Key:アメリカ
    //国名:アメリカ、都市名:ロサンゼルス
    //国名:アメリカ、都市名:シアトル
}

class City
{
    public string CountryName { get; set; } = "";
    public string CityName { get; set; } = "";
}

応用

複数の値でグループ化する場合は匿名型を使います。

複数の値でグループ化するソース例
List<City> cityList = new List<City>();

cityList.Add(new City { CountryName = "日本", CityName = "東京" ,AreaName = "新宿区" });
cityList.Add(new City { CountryName = "日本", CityName = "東京", AreaName = "品川区" });
cityList.Add(new City { CountryName = "日本", CityName = "大阪" , AreaName = "中央区" });
cityList.Add(new City { CountryName = "日本", CityName = "大阪", AreaName = "北区" });

//国名と都市名をグループ化するプロパティとして選択してグループ化する。
var groupByCountryName = cityList.GroupBy(x => new { x.CountryName ,x.CityName});

foreach (var groupingCity in groupByCountryName)
{
    //Keyの中身はGroupByでグループ化したプロパティです。
    //この例では[CountryName]プロパティと[CityName]プロパティが値として取得できます。
    Console.WriteLine($"Key:{groupingCity.Key.CountryName}{groupingCity.Key.CityName}");

    foreach (var city in groupingCity)
    {
        //グループ化した結果を列挙しています。
        Console.WriteLine($"国名:{city.CountryName}、都市名:{city.CityName}、区名:{city.AreaName}");
    }

    //出力
    //Key:日本、東京
    //国名:日本、都市名:東京、区名:新宿区
    //国名:日本、都市名:東京、区名:品川区
    //Key:日本、大阪
    //国名:日本、都市名:大阪、区名:中央区
    //国名:日本、都市名:大阪、区名:北区
}

class City
{
    public string CountryName { get; set; } = "";
    public string CityName { get; set; } = "";
    public string AreaName { get; set; } = "";
}

KeyのValue部分のリストを取得したい場合はSingle()を使います。

KeyのValue部分のリストを取得するソース例
List<City> cityList = new List<City>();

cityList.Add(new City { CountryName = "日本", CityName = "東京" ,AreaName = "新宿区" });
cityList.Add(new City { CountryName = "日本", CityName = "東京", AreaName = "品川区" });
cityList.Add(new City { CountryName = "日本", CityName = "大阪" , AreaName = "中央区" });
cityList.Add(new City { CountryName = "日本", CityName = "大阪", AreaName = "北区" });

//国名と都市名をグループ化するプロパティとして選択してグループ化する。
var groupByCountryName = cityList.GroupBy(x => new { x.CountryName ,x.CityName}).ToList();

foreach (var groupingCity in groupByCountryName)
{
    //Keyの中身はGroupByでグループ化したプロパティです。
    //この例では[CountryName]プロパティと[CityName]プロパティが値として取得できます。
    Console.WriteLine($"Key:{groupingCity.Key.CountryName}{groupingCity.Key.CityName}");

    //Keyは必ず唯一の要素になるのでSingle()を使ってValueの部分を取得しています。
    var groupingCityList = groupByCountryName.Single(x => x.Key == groupingCity.Key).ToList();

    foreach (var city in groupingCityList)
    {
        //グループ化した結果を列挙しています。
        Console.WriteLine($"国名:{city.CountryName}、都市名:{city.CityName}、区名:{city.AreaName}");
    }

    //出力
    //Key:日本、東京
    //国名:日本、都市名:東京、区名:新宿区
    //国名:日本、都市名:東京、区名:品川区
    //Key:日本、大阪
    //国名:日本、都市名:大阪、区名:中央区
    //国名:日本、都市名:大阪、区名:北区
}

class City
{
    public string CountryName { get; set; } = "";
    public string CityName { get; set; } = "";
    public string AreaName { get; set; } = "";
}

注意事項
GroupBy()を遅延実行で使用する場合はSingle()を使うと例外が発生します。Single()を使って値を取得する場合はToList()等を使って値を確定させて下さい。上記のソースのGroupBy()を遅延実行になるように書き換えると例外が発生します。

遅延実行に変更すると例外が発生します。
//国名と都市名をグループ化するプロパティとして選択してグループ化する。               ↓.Tolist()を消して遅延実行にした。
var groupByCountryName = cityList.GroupBy(x => new { x.CountryName ,x.CityName});
2
3
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?