LoginSignup
46
37

More than 3 years have passed since last update.

ストップforeach!LINQで集合/結合する

Last updated at Posted at 2018-04-26

1. はじめに

2年間C#プロジェクトに携わった中でよく使ってきたLINQまとめ
に引き続きLINQ記事です。
LINQを知らないと、コレクションを扱う際に、ついforeachを使ってしまうかと思います。
そのforeach、ちょっと待ってください!!!
LINQを使って簡単に集合・結合操作が行えるのでまとめていきたいと思います。

2. 集合

2-1. Union (和集合)

コレクション同士を連結します。
重複するデータがある場合は1件のみに絞られます。

var listA = new string[] { "りんご", "ばなな", "ぶどう", "みかん" };
var listB = new string[] { "さくらんぼ", "ばなな", "もも", "りんご" };

var list = listA.Union(listB);

foreach (var item in list)
{
    System.Console.WriteLine(item);
}

<結果>
Union.PNG

2-2. Concat (和集合)

コレクション同士を連結します。
重複するデータがある場合はそのまま連結されます。(Union Allのイメージです。)

void Main()
{
    var listA = new string[] { "りんご", "ばなな", "ぶどう", "みかん" };
    var listB = new string[] { "さくらんぼ", "ばなな", "もも", "りんご" };

    var list = listA.Concat(listB);

    foreach (var item in list)
    {
        System.Console.WriteLine(item);
    }
}

<結果>
Concat.PNG

2-3. Intersect (積集合)

2つのコレクションのどちらにも含まれている要素のみ抽出します。

var listA = new string[] { "りんご", "ばなな", "ぶどう", "みかん" };
var listB = new string[] { "さくらんぼ", "ばなな", "もも", "りんご" };

var list = listA.Intersect(listB);

foreach (var item in list)
{
    System.Console.WriteLine(item);
}

<結果>
Intersect.PNG

2-4. Except (差集合)

左側のコレクション要素から、右側のコレクション要素を引きます。

var listA = new string[] { "りんご", "ばなな", "ぶどう", "みかん" };
var listB = new string[] { "さくらんぼ", "ばなな", "もも", "りんご" };

var list = listA.Except(listB);

foreach (var item in list)
{
    System.Console.WriteLine(item);
}

<結果>
Except.PNG

3. 結合

3-1. Join (内部結合)

指定したキーに基づいて、コレクションを内部結合します。
以下の例では「社員.部署ID」と「部署.部署ID」をキーとして結合し、
1つのコレクションを作成しています。

// 従業員
public class Employee
{
    // 従業員ID
    public int Id { get; set;}
    // 部署ID
    public int DepartmentId { get; set;}
    // 従業員名
    public string Name { get; set;}
}

// 部署
public class Department
{
    // 部署ID
    public int Id { get; set;}
    // 部署名
    public string Name { get; set;}
}

// 従業員データ
var employeeList = new List<Employee>
{
    new Employee { Id = 100, Name = "佐藤", DepartmentId = 1 },
    new Employee { Id = 101, Name = "鈴木", DepartmentId = 2 },
    new Employee { Id = 102, Name = "高橋", DepartmentId = 3 },
    new Employee { Id = 103, Name = "田中", DepartmentId = 2 },
    new Employee { Id = 104, Name = "伊藤", DepartmentId = 1 },
    new Employee { Id = 105, Name = "渡辺", DepartmentId = 3 },
    new Employee { Id = 106, Name = "山本", DepartmentId = 1 },
};

// 部署データ
var departmentList = new List<Department>
{
    new Department { Id = 1, Name = "開発部" },
    new Department { Id = 2, Name = "研究部" },
    new Department { Id = 3, Name = "総務部" }
};

var list = employeeList.Join(departmentList, e => e.DepartmentId, d => d.Id, (e, d) => new
{
    EmployeeId = e.Id,
    EmployeeName = e.Name,
    DepartmentName = d.Name
});

foreach (var item in list)
{
    System.Console.WriteLine(item);
}

<結果>
Join.PNG

3-2. GroupJoin (外部結合)

指定したキーに基づいて、コレクションを外部結合します。
以下の例では、「社員.部署ID」と「部署.部署ID」をキーとして結合しますが、
紐づくキーがない場合は部署にnullを設定するようにしています。

// 従業員
public class Employee
{
    // 従業員ID
    public int Id { get; set;}
    // 部署ID(null許容型)
    public int? DepartmentId { get; set;}
    // 従業員名
    public string Name { get; set;}
}

// 部署
public class Department
{
    // 部署ID
    public int Id { get; set;}
    // 部署名
    public string Name { get; set;}
}

void Main()
{
    // 従業員データ
    var employeeList = new List<Employee>
    {
        new Employee { Id = 100, Name = "佐藤", DepartmentId = 1 },
        new Employee { Id = 101, Name = "鈴木", DepartmentId = 2 },
        new Employee { Id = 102, Name = "高橋", DepartmentId = null },
        new Employee { Id = 103, Name = "田中", DepartmentId = null },
        new Employee { Id = 104, Name = "伊藤", DepartmentId = 1 },
        new Employee { Id = 105, Name = "渡辺", DepartmentId = 3 },
        new Employee { Id = 106, Name = "山本", DepartmentId = 1 },
    };

    // 部署データ
    var departmentList = new List<Department>
    {
        new Department { Id = 1, Name = "開発部" },
        new Department { Id = 2, Name = "研究部" },
        new Department { Id = 3, Name = "総務部" }
    };

    var list = employeeList.GroupJoin(departmentList, e => e.DepartmentId, d => d.Id, (e, d) => new
    {
        EmployeeId = e.Id,
        EmployeeName = e.Name,
        Departments = d.DefaultIfEmpty()
    })
    .SelectMany(d => d.Departments, (e, d) => new
    {
        EmployeeId = e.EmployeeId,
        EmployeeName = e.EmployeeName,
        DepartmentName = d != null ? d.Name : "所属なし"
    });

    foreach (var item in list)
    {
        System.Console.WriteLine(item);
    }
}

<結果>
GroupJoin.PNG

4. おわりに

コレクション操作はいろんな場面で使えるので、覚えておくととても便利ですね!
他にもありましたら随時更新させて頂きます。

46
37
0

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
46
37