Top > C# > LINQ

LINQ

配列やListなどのコレクション( IEnumerable<T> インターフェイスを実装する) に対し組み込みで(拡張メソッドとして)提供されるデータを問い合わせる手段。
実装方法として、SQLっぽくかけるクエリ式と、拡張メソッドのメソッドチェーンで記載するメソッド式の2つがある。
ここではメソッド式を利用する場合の基礎的な部分のメモ。

基礎の基礎

以下のようなメソッドを組み合わせて利用する。
これらは基本的にIEnumerable<T>を返すのでメソッドチェーンで記述できる。
なお、メソッドは上から実行されるので、処理効率を意識する必要はある。
(※内部的にはforeachで回しているだけ。)

dataの前提となるコード


        private class BurgerShop
        {
            public int Id { get; set; }
            public string Name { get; set; } = string.Empty;
            public string Description { get; set; } = string.Empty;
            public string PriceRange { get; set; } = string.Empty;
            public string NumberOfStore { get; set; } = string.Empty;
            public int Score { get; set; }
        }

        private List<BurgerShop> GetBurgerShopList()
        {
            var list = new List<BurgerShop>();

            list.Add(new BurgerShop()
            {
                Id = 1,
                Name = "マクドナルド",
                Description = "てりやきバーバーこそ至高",
                PriceRange = "低価格",
                NumberOfStore = "多い",
                Score = 95,
            });
            list.Add(new BurgerShop()
            {
                Id = 2,
                Name = "バーガーキング",
                Description = "ワッパーがでかい。肉がBBQみたいで香ばしい",
                PriceRange = "普通",
                NumberOfStore = "普通",
                Score = 80
            });
            list.Add(new BurgerShop()
            {
                Id = 3,
                Name = "ロッテリア",
                Description = "マックの劣化版。",
                PriceRange = "普通",
                NumberOfStore = "多い",
                Score = 50
            });
            list.Add(new BurgerShop()
            {
                Id = 4,
                Name = "ウェンディーズ",
                Description = "肉が四角い",
                PriceRange = "高い",
                NumberOfStore = "少ない",
                Score = 75
            });
            list.Add(new BurgerShop()
            {
                Id = 5,
                Name = "モスバーガー",
                Description = "美味しいけど高級路線。注文を受けてから手作り。",
                PriceRange = "高い",
                NumberOfStore = "多い",
                Score = 75
            });
            list.Add(new BurgerShop()
            {
                Id = 6,
                Name = "フレッシュネスバーガー",
                Description = "モスみたいなもん",
                PriceRange = "高い",
                NumberOfStore = "普通",
                Score = 70
            });
            list.Add(new BurgerShop()
            {
                Id = 7,
                Name = "ドムドム",
                Description = "ドム像くんが可愛い。カニのバーガー。",
                PriceRange = "普通",
                NumberOfStore = "少ない",
                Score = 95
            });
            list.Add(new BurgerShop()
            {
                Id = 8,
                Name = "ラッキーピエロ",
                Description = "函館といったら。チャイニーズチキンバーガー",
                PriceRange = "普通",
                NumberOfStore = "少ない",
                Score = 80
            });

            return list;
        }
    

Select

必要な項目を記述する。
複数項目が必要な場合は、匿名クラスを記述する。


    var result1 = data.Select(x => x.Name);
    var result2 = data.Select(x => new { x.Name, x.Description });

Where

絞り込み条件式(論理値を返す)を記述する。


    var result1 = data.Where(x => 90 <= x.Score);
    var result2 = data.Where(x => x.Description.Contains("肉") && x.Score >= 80);

OrderBy

OrderBy(昇順)、OrderByDescending(降順)
複数の条件でソートする場合、ThenBy(昇順)、ThenByDescending(降順)をメソッドチェーンで書く


    var result1 = data.OrderBy(x => x.Score).ThenBy(x => x.Id);
    var result2 = data.OrderByDescending(x => x.Score).ThenByDescending(x => x.Name);

GroupBy

Select同様にグルーピングしたい項目を返却する、複数ある場合は匿名クラスで返却する。
返却されるIEnumerable<T>の中身はIGrouping型であり、 ここから集計値を(Averageなど)を取得する。


    var result1 = data.GroupBy(x => x.PriceRange)
        .Select(x => new
        {
            x.Key,
            ScoreAerage = x.Average(y => y.Score)
        });

    var result2 = data.GroupBy(x => new { x.PriceRange, x.NumberOfStore })
        .Select(x => new
        {
            x.Key.PriceRange,
            x.Key.NumberOfStore,
            ScoreAerage = x.Average(y => y.Score),
            ScoreMin = x.Min(y => y.Score),
            ScoreMax = x.Max(y => y.Score),
            Count = x.Count()
        });