やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

C#の概念 LINQ(グループ結合)

 階層構造データを作成するときに便利。

成果物

情報源

コード

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

class Person
{
    public string Name { get; set; }
}
class Pet
{
    public string Name { get; set; }
    public Person Owner { get; set; }
}
class Main {
    private List<Person> persons;
    private List<Pet> pets;
    public void Run() {
        persons = CreatePersons();
        pets = CreatePets();
        Show(Query());
    }
    private List<Person> CreatePersons() {
        return new List<Person>() {
            new Person { Name="A" },
            new Person { Name="B" },
        };
    }
    private List<Pet> CreatePets() {
        return new List<Pet>() {
            new Pet { Name="a", Owner=persons[0] },
            new Pet { Name="b", Owner=persons[0] },
            new Pet { Name="c", Owner=persons[1] },
        };
    }
    private IEnumerable<dynamic> Query() {
        return  from person in persons
                join pet in pets on person equals pet.Owner into gj
                select new { OwnerName=person.Name, Pets=gj };
    }
    private void Show(in IEnumerable<dynamic> query) {
        foreach (var item in query) {
            Console.WriteLine($"OwnerName={item.OwnerName}");
            foreach (var pet in item.Pets) {
                Console.WriteLine($"  PetName={pet.Name}");
            }
        }
    }
}
OwnerName=A
  PetName=a
  PetName=b
OwnerName=B
  PetName=c

疑問

 これはグループなのか?

from person in persons
join pet in pets on person equals pet.Owner into gj
select new { OwnerName=person.Name, Pets=gj };
foreach (var item in query) {
    Console.WriteLine($"OwnerName={item.OwnerName}");
    foreach (var pet in item.Pets) {
        Console.WriteLine($"  PetName={pet.Name}");
    }
}

 joinで内部結合した複数の行はIEnumerable<Pet>コレクション型でまとめられていると思われる。それをグループと呼ぶべきなのか? group句は使っていないしIGrouping<TKey, TSource>コレクション型でもないと思うのだが。

 一般的なグループ化という意味ならそれでもいいと思う。だが、今まではgroup句した結果をグループと読んでいたのだから統一性がなくなってしまう。コレクション型が異なるからには、join intogroup byは明確に区別すべきだと思う。

 ではどう呼ぶべきなのか? 集合? コレクション? IEnumerable<Pet>が最も正確だと思う。

 情報源では、そんな呼び方は冗長だから一緒くたに「グループ結合」と呼んだのだろう。「内部結合」などなんちゃら結合の一種かと思ってしまうため、やはり紛らわしい。もっとも、SQLの結合について知っていればそんな勘違いはしないが。

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux