なんか続いてしまいました。LINQの使い方その2です。(*’▽’)
その1は以下の記事です。
【C#】LINQの使い方(その1)
GroupBy使い方
今回はGroupByについてです。
とはいっても、指定した項目についてグルーピングするだけなので
実際のサンプルコードを見てください。
以下のクラスはCSVファイルを取り込んで、
ソートしたり重複データを探したりしてみるサンプルです。
(酔っ払いつつ書いたので動作保証なし!)
public class UserData
{
private int id;
private string name;
private int age;
public int Id { get => id; set => id = value; }
public string Name { get => name; set => name = value; }
public int Age { get => age; set => age = value; }
public UserData(int id, string name, int age)
{
this.Id = id;
this.Name = name;
this.Age = age;
}
}
internal class CsvData
{
protected List<UserData> UserDataList;
public CsvData(string filePath)
{
using (StreamReader sr = new StreamReader(filePath))
{
UserDataList = new List<UserData>();
while (!sr.EndOfStream)
{
var line = sr.ReadLine();
var values = line.Split(',');
if (values.Length != 3)
{
throw new Exception("CSVフォーマットが異なる。");
}
try
{
int id = int.Parse(values[0]);
string name = values[1];
int age = int.Parse(values[2]);
UserDataList.Add(new UserData(id, name, age));
}
catch (Exception)
{
throw new Exception("データ型が異なる。");
}
}
}
}
/// <summary>
/// 読み込みデータリスト取得
/// </summary>
/// <returns></returns>
public List<UserData> GetData() => UserDataList;
/// <summary>
/// ソート済みデータ取得
/// </summary>
/// <returns></returns>
public IOrderedEnumerable<UserData> GetSortedata()
=> UserDataList.OrderBy(x => x.Id)
.ThenBy(x => x.Age);
/// <summary>
/// 重複したデータを取得
/// </summary>
/// <returns>重複したデータのリスト</returns>
public IEnumerable<(int Id, string Name, int Age, int Count)> GetDuplicateData()
=> UserDataList.GroupBy(x => (x.Id, x.Name, x.Age))
.Select(x => (Id: x.Key.Id, Name: x.Key.Name, Age: x.Key.Age, Count: x.Count()))
.Where(x => x.Count > 1);
}
動作確認用ソース
以下の順に結果を表示しています。
- CSVファイル読み込み後
- 読み込みデータソート後
- 重複データ取得
CsvData csvData = new CsvData(@"sample.csv");
foreach (var item in csvData.GetData())
{
Console.WriteLine("id:{0,3} name:{1,-10} age:{2,3}", item.Id, item.Name, item.Age);
}
Console.WriteLine("==========================");
foreach (var item in csvData.GetSortedata())
{
Console.WriteLine("id:{0,3} name:{1,-10} age:{2,3}", item.Id, item.Name, item.Age);
}
Console.WriteLine("==========================");
foreach (var item in csvData.GetDuplicateData())
{
Console.WriteLine("id:{0,3} name:{1,-10} age:{2,3}", item.Id, item.Name, item.Age);
}
実行
読み込みデータ
サンプルデータ作成ツールでテキトーに作られたデータです。
1,宮村 翠,31 2,柴田 俊史,26 3,大里 里佳,34 4,向田 洋文,23 121,川合 章子,52 3,大里 里佳,34 2,柴田 俊史,26 2,柴田 俊史,27 2,柴田 俊史1,26
実行結果
重複されたデータのみが取得されてます。
id: 1 name:宮村 翠 age: 31 id: 2 name:柴田 俊史 age: 26 id: 3 name:大里 里佳 age: 34 id: 4 name:向田 洋文 age: 23 id:121 name:川合 章子 age: 52 id: 3 name:大里 里佳 age: 34 id: 2 name:柴田 俊史 age: 26 id: 2 name:柴田 俊史 age: 27 id: 2 name:柴田 俊史1 age: 26 ========================== id: 1 name:宮村 翠 age: 31 id: 2 name:柴田 俊史 age: 26 id: 2 name:柴田 俊史 age: 26 id: 2 name:柴田 俊史1 age: 26 id: 2 name:柴田 俊史 age: 27 id: 3 name:大里 里佳 age: 34 id: 3 name:大里 里佳 age: 34 id: 4 name:向田 洋文 age: 23 id:121 name:川合 章子 age: 52 ========================== id: 2 name:柴田 俊史 age: 26 id: 3 name:大里 里佳 age: 34
その3はない!(;´Д`)
