【C#】LINQの使い方(その2)

なんか続いてしまいました。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);
}

動作確認用ソース

以下の順に結果を表示しています。

  1. CSVファイル読み込み後
  2. 読み込みデータソート後
  3. 重複データ取得
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はない!(;´Д`)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です