こんにちは。きわさです。
前回に引き続き、C#のLinqについてです。
今回はJoinです。
二つのリストから新しいリストを生成します。
例えば以下のようなユーザークラスと会社クラスがあり、
ユーザークラスのCompanyIdには、所属する会社(Company)のId入ります。
public class User { public int Id { get; set; } public string Name { get; set; } public int CompanyId { get; set; } } public class Company { public int Id { get; set; } public string Name { get; set; } public DateTime Date { get; set; } public string Address { get; set; } }
そして、以下のように全ユーザー、全会社のリストがそれぞれあるとします。
List<User> userList = new List<User>() { // 全ユーザーの情報 } List<Company> companyList = new List<Company>() { // 全会社の情報 }
そこで、あるユーザーの所属する会社名と住所を知りたくなりました。
Linqを使わずに書くと以下のようなループループな感じになりかねません。
var userId = 3; // 対象ユーザー Company userCompany = null; foreach (var user in userList) { if (user.Id == userId) { foreach (var company in companyList) { if (user.CompanyId == company.Id) { userCompany = company; break; } } break; } }
前回のWhereを使ってみると次のように書くことができます。
var user = userList.Where(u => u.Id == userId).First(); var company = companyList.Where(c => c.Id == user.CompanyId).First();
.First()は1件目の要素を取得できます。
.Where(u => u.Id == userId).First()は直接
.First(u => u.Id == userId) と書くこともできます。
上記の場合のように、対象ユーザー一人分等であれば、よいかもしれませんが、
複数のユーザーの会社情報を一覧にしたい場合などではJoinが使えます。
var list = userList.Join(companyList, u => u.CompanyId, c => c.Id, (u, c) => new { UserId = u.Id, UserName = u.Name, CompanyName = c.Name, CompanyAddress = c.Address, }) .ToList();
このようにすると、listは ユーザーID、氏名、会社名、会社住所をメンバにもつオブジェクトのリストとなります。
new { } の部分は 定義済みクラスで new XXX() { } のようにもできます。
あとは該当のユーザーの情報をとるなり、全ユーザーを一覧表示するなり、できます。
ループループしてなくてよいですね。