C#

【C#入門】LINQ(リンク)とは?わかりやすく解説!

こんにちは、リバティエンジニア[?]のたくやです。 現役エンジニアとしてアプリケーション開発やWeb制作、SEOやブログ運営をしています。

今回は、まだLINQ(リンク)を使いこなせていない方や、初心者でこれから勉強したい方向けの記事です。

C#のLINQ(リンク)とは?

そもそもC#におけるLINQ(リンク)なんなのでしょうか。

公式では次のように解説されています。
みんな大好きMSDN(マイクロソフト公式)を見てみましょう。

統合言語クエリ (LINQ) は、C# 言語への直接的なクエリ機能の統合に基づくテクノロジのセットの名前です。 これまでは、データに対するクエリは、コンパイル時の型チェックや IntelliSense のサポートがない単純な文字列として表現されてきました。 さらに、SQL データベース、XML ドキュメント、さまざまな Web サービスなど、各種データ ソースの異なるクエリ言語を学習する必要があります。 LINQ では、クエリは、クラス、メソッド、イベントと同様に、ファースト クラスの言語コンストラクトです。

難しいですよね。。
私もこれを読むのは疲れます。

とりあえず今は「foreach」の強化版とでも覚えておきましょう。
「foreach」についてはよかったら下の記事を参考にしてみてください。

[C#] 繰り返し処理(for, while, foreach)について

LINQ(リンク)とSQLは関係ありません

C#のLINQ(リンク)はよくSQLと同じと誤解されますが、全く関係ないので注意してください。

LINQの構文の中では「from」「where」「orderby」「select」などのSQLでも見るキーワードを使うので勘違いされる方が多いみたいですね。

C#のLINQ(リンク)の使い方

それでは LINQ メソッドの使い方を見ていきましょう。

要素の取得


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

namespace LinqTest
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            var list = new List { 1, 84, 95, 95, 40, 6 };

            // list の最初の要素を取得する
            Console.WriteLine("First: " + list.First());

            // list の最後の要素を取得する
            Console.WriteLine("Last: " + list.Last());
        }
    }
}

[実行結果]


First: 1
Last: 6

集計


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

namespace LinqTest
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            var list = new List { 1, 84, 95, 95, 40, 6 };

            // list の最大値を取得
            Console.WriteLine("Max: " + list.Max());

            // list の最小値を取得
            Console.WriteLine("Min: " + list.Min());

            // list の平均値を取得
            Console.WriteLine("Average: " + list.Average());

            // list の合計値を取得
            Console.WriteLine("Sum: " + list.Sum());

            // list の要素値を取得
            Console.WriteLine("Count: " + list.Count());
        }
    }
}

[実行結果]


Max: 95
Min: 1
Average: 53.5
Sum: 321
Count: 6

変換


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

namespace LinqTest
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            var list = new List { 1, 84, 95, 95, 40, 6 };

            // list を配列に変換
            int[] array = list.ToArray();
            Console.WriteLine("=== array ===");
            foreach (var x in array)
            {
                Console.WriteLine(x);
            }

            // list を object 型の List に変換
            List<object> objectList = list.Cast<object>().ToList();
            Console.WriteLine("=== objectList ===");
            foreach (var x in objectList)
            {
                Console.WriteLine(x);
            }
        }
    }
}

[実行結果]


=== array ===
1
84
95
95
40
6
=== objectList ===
1
84
95
95
40
6    

複数要素の取得


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

namespace LinqTest
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            var list = new List { 1, 84, 95, 95, 40, 6 };

            // list から重複を除いた要素を取得する
            var distinctList = list.Distinct();
            Console.WriteLine("=== distinctList ===");
            foreach (var x in distinctList)
            {
                Console.WriteLine(x);
            }

            // list の先頭から指定された数の要素をスキップして残りの要素を取得する
            var skipList = list.Skip(3);
            Console.WriteLine("=== skipList ===");
            foreach (var x in skipList)
            {
                Console.WriteLine(x);
            }

            // list の先頭から指定された数の要素を取得する
            var takeList = list.Take(3);
            Console.WriteLine("=== takeList ===");
            foreach (var x in takeList)
            {
                Console.WriteLine(x);
            }
        }
    }
}

[実行結果]


=== distinctList ===
1
84
95
40
6
=== skipList ===
95
40
6
=== takeList ===
1
84
95

判定


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

namespace LinqTest
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            var list = new List { 1, 84, 95, 95, 40, 6 };

            // list のすべての要素が 100 未満かどうか
            Console.WriteLine("All: " + list.All(x => x < 100));

            // list のいずれかの要素が 0 未満かどうか
            Console.WriteLine("Any: " + list.Any(x => x < 0));

            // list に値が 40 の要素が含まれてるかどうか
            Console.WriteLine("Contains: " + list.Contains(40));
        }
    }
}

[実行結果]


All: True
Any: False
Contains: True

集合


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

namespace LinqTest
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            var list1 = new List { 1, 84, 95, 95, 40, 6 };
            var list2 = new List { 1, 16, 39, 33, 7, 84 };

            // 和集合を取得する
            var unionList = list1.Union(list2);
            Console.WriteLine("=== unionList ===");
            foreach (var x in unionList)
            {
                Console.WriteLine(x);
            }

            // 差集合を取得する
            var exceptList = list1.Except(list2);
            Console.WriteLine("=== exceptList ===");
            foreach (var x in exceptList)
            {
                Console.WriteLine(x);
            }

            // 積集合を取得する
            var intersectList = list1.Intersect(list2);
            Console.WriteLine("=== intersectList ===");
            foreach (var x in intersectList)
            {
                Console.WriteLine(x);
            }
        }
    }
}

[実行結果]


=== unionList ===
1
84
95
40
6
16
39
33
7
=== exceptList ===
95
40
6
=== intersectList ===
1
84

ソート


using System;
using System.Linq;

namespace LinqTest
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            var fruitList = new[] {
                new  {Name = "りんご", Price = 300},
                new  {Name = "バナナ", Price = 200},
                new  {Name = "パイナップル", Price = 1000},
                new  {Name = "いちご", Price = 500},
            };

            // fruitList を Price が昇順になるように並び替える
            var orderByList = fruitList.OrderBy(x => x.Price);
            Console.WriteLine("=== orderByList ===");
            foreach (var x in orderByList)
            {
                Console.WriteLine(x);
            }

            // fruitList を Price が降順になるように並び替える
            var orderByDescendingList = fruitList.OrderByDescending(x => x.Price);
            Console.WriteLine("=== orderByDescendingList ===");
            foreach (var x in orderByDescendingList)
            {
                Console.WriteLine(x);
            }

            // fruitList を逆順に並び替える
            var reverseList = fruitList.Reverse();
            Console.WriteLine("=== reverseList ===");
            foreach (var x in reverseList)
            {
                Console.WriteLine(x);
            }
        }
    }
}

[実行結果]


=== orderByList ===
{ Name = バナナ, Price = 200 }
{ Name = りんご, Price = 300 }
{ Name = いちご, Price = 500 }
{ Name = パイナップル, Price = 1000 }
=== orderByDescendingList ===
{ Name = パイナップル, Price = 1000 }
{ Name = いちご, Price = 500 }
{ Name = りんご, Price = 300 }
{ Name = バナナ, Price = 200 }
=== reverseList ===
{ Name = いちご, Price = 500 }
{ Name = パイナップル, Price = 1000 }
{ Name = バナナ, Price = 200 }
{ Name = りんご, Price = 300 }    

まとめ

どうでしょうか。
今回は、C#のLINQ(リンク)について初心者の方でも簡単に理解できるようにサンプルコードも載せてご紹介しました。

LINQ(リンク)は少しややこしく感じて難しいと思ってしまうかもしれませんが、使えるようになると便利なので今回をきっかけに是非使ってみてください。

他にもC#の記事がありますので、よかったら参考にしてみてください。

C#2.0 で追加された「匿名メソッド」とは?

【初心者必見】現役エンジニアがおすすめするプログラミングスクール

[C#] 可変長引数をつかってみる


Copyright© FUNA BLOG , 2020 All Rights Reserved.