こんにちは。きわさです。
前回に引き続き、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() { } のようにもできます。
あとは該当のユーザーの情報をとるなり、全ユーザーを一覧表示するなり、できます。
ループループしてなくてよいですね。
