C# ゼロから理解するラムダ式:LINQの代表的な機能を解説 #16

これまでにLINQの学習としてWhereメソッド、Selectメソッドを紹介してきました。どちらもよく使うものであり、かつLINQを代表するメソッドですのでしっかりと復習もしておきましょう。

今回はLINQでよく使う機能を一気にまとめ上げたいと思います。ここで紹介するLINQの機能は、現場でもよく使用する厳選したものを紹介していきますので、どれもしっかりと覚えておきましょう。

要素を取得する

コレクションの中から要素を取得するときに使用する機能です。以下に挙げる4つの機能は本当によく使用するので覚えておく必要があります。

using System;
using System.Linq;

namespace App18
{
    class Program
    {
        static void Main(string[] args)
        {
            var list = Enumerable.Range(1, 20);
            
            //要素の一番最初を取得する
            var first = list.First();
            Console.WriteLine($"First():{ first }");
            
            //要素の一番最初を取得する(存在がなければnullが返却)
            var firstOrDefault = list.FirstOrDefault();
            Console.WriteLine($"FirstOrDefault():{ firstOrDefault }");

            //要素の一番最後を取得する
            var last = list.Last();
            Console.WriteLine($"Last():{ last }");

            //要素の一番最後を取得する(存在がなければnullが返却)
            var lastOrDefault = list.LastOrDefault();
            Console.WriteLine($"LastOrDefault():{ lastOrDefault }");

            Console.ReadLine();
        }
    }
}

「First」と「FirstOrDefault」はコレクションの最初の要素を取得します。個人的には「FirstOrDefault」をよく使いますね。「Firstメソッド」では最初の要素が存在しない場合は例外で落ちてしまいます。

「FirstOrDefaultメソッドは最初の要素が存在しない場合はnullが返ってくるので、使用後にnullチェックを怠らなければ例外判定をする必要がありません。Lastメソッド、LastOrDefaultメソッドはFirst、FirstOrDefaultメソッドの逆で要素の一番最後を取得してくれます。

要素を変換する

ToArrayメソッド、ToListメソッドをよく使うので紹介します。Listを配列に変換したり、配列をListに変換したりできます。また遅延実行形式のコレクションに対してToListメソッドを使用することでインスタンス化することが可能です。

using System;
using System.Collections.Generic;
using System.Linq;

namespace App19
{
    class Program
    {
        static void Main(string[] args)
        {
            var list = new List<int>() { 1, 2, 3, 4, 5 };
            int[] listToArray = list.ToArray();//List→配列
            foreach(var item in listToArray)
            {
                Console.WriteLine("ToArray():" + item.ToString());
            }

            var array = new int[5] { 1, 2, 3, 4, 5 };
            List arrayToList = array.ToList();//配列→List
            foreach (var item in arrayToList)
            {
                Console.WriteLine("ToList():" + item.ToString());
            }
            Console.ReadLine();
        }
    }
}

複数要素を取得する

複数の要素を取得するためのメソッドがLINQでは用意されています。特に先頭から指定した数をスキップして残りを取得したり、先頭から指定した数の個数を取得するなどがよく使用します。

using System;
using System.Linq;

namespace App20
{
    class Program
    {
        static void Main(string[] args)
        {
            var list = Enumerable.Range(1, 10);

            //先頭から2つの要素を飛ばして残りを取得する
            var skipList = list.Skip(2);
            foreach(var item in skipList)
            {
                Console.WriteLine($"Skip():{ item.ToString() }");
            }

            Console.WriteLine();

            //先頭から4つの要素を取得する
            var takeList = list.Take(4);
            foreach (var item in takeList)
            {
                Console.WriteLine($"Take():{ item.ToString() }");
            }

            Console.ReadLine();
        }
    }
}

Skipメソッドは先頭から指定した数を飛ばして残りを取得し、Takeメソッドは先頭から指定した数だけ要素を取得できます。メソッドチェーンを利用して、射影したりフィルタリングしてから使用すると使い勝手が良くなります。

要素を判定する

コレクションに対する判定を行う機能はよく使います。例えば「すべての要素が〇〇を満たしているか」や「〇〇を満たす要素が存在するか」、また「〇〇を持つ要素が存在するか」などが行えます。

using System;
using System.Collections.Generic;
using System.Linq;

namespace App21
{
    class Program
    {
        static void Main(string[] args)
        {
            var list = new List<int>() { 10, 15, 22, };

            //すべての要素が10以上であるか
            var allOne = list.All(x => x >= 10);
            Console.WriteLine($"All(x => x <= 10):{ allOne }");
            //すべての要素が10未満であるか
            var allTwo = list.All(x => x < 10);
            Console.WriteLine($"All(x => x < 10):{ allTwo }");


            var listTwo = new List<int>() { 5, 10, 99, };

            //10未満の要素が存在するか
            var anyOne = listTwo.Any(x => x < 10);
            Console.WriteLine($"Any(x => x < 10):{ anyOne }");


            //100以上の要素が存在するか
            var anyTwo = listTwo.Any(x => x >= 100);
            Console.WriteLine($"Any(x => x >= 100):{ anyTwo }");


            var listThree = new List<int>() { 10, 11, 12 };

            //要素に11を持っているか
            var containsOne = listThree.Contains(11);
            Console.WriteLine($"Contains(11):{ containsOne }");

            //要素に100を持っているか
            var containsTwo = listThree.Contains(100);
            Console.WriteLine($"Contains(100):{ containsTwo }");

            Console.ReadLine();
        }
    }
}

要素をソートする

コレクションの要素をソートする機能もLINQには備わっています。数値型のデータ型であれば降順・昇順に並び変えることが可能ですし、コレクションの順番を逆にすることも可能です。

using System;
using System.Collections.Generic;
using System.Linq;

namespace App22
{
    class Program
    {
        static void Main(string[] args)
        {
            var list = new List<int>() { 5, 1, 4, 3, 2, };

            //キーを指定して並び替える
            var orderBy = list.OrderBy(x => x);
            foreach(var item in orderBy)
            {
                Console.WriteLine($"OrderBy :{ item.ToString() }");
            }

            Console.WriteLine();

            //キーを指定して逆順に並び替える
            var orderByDecend = list.OrderByDescending(x => x);
            foreach (var item in orderByDecend)
            {
                Console.WriteLine($"OrderByDescending :{ item.ToString() }");
            }

            Console.WriteLine();

            //コレクションを逆転させる
            list.Reverse();
            foreach (var item in list)
            {
                Console.WriteLine($"Reverse :{ item.ToString() }");
            }
            Console.ReadLine();
        }
    }
}

要素の取得や変換、複数要素の取得、要素の判定、最後にソートについて解説してきました。これらのメソッドは現場でもよく使用するものですので、覚えておくと武器になります。ここで紹介したLINQはよく使いものだけであり、もっとほかにもたくさんの機能が用意されているので、是非とも自分で調べたり使ってみてください。

LINQは奥が深く、知らない機能がたくさん実装されていますので、あなた自身で使ってみて判断を下していったほうが絶対に良いですね。あなたにとって便利な機能を見つけられるはずです。