LINQのSelectメソッドの書き方3選|LINQについてなどを紹介
- システム
エンジニア - LINQのSelectってforやForEachとどのような違いがあるんですか?
- プロジェクト
マネージャー - 繰り返し処理という意味では同じですが、条件によってはSelectの方が使いやすいことがありますね。早速どういうことができるか見ていきましょう。
LINQについて
Selectメソッドについて
LINQのSelectメソッドとは、さまざまなデータ形式に対し、よく使われる処理のクエリをライブラリー化したものです。
LINQSelectメソッドでは、コレクションの処理を一括して行ってしまいます。そのため、for文やForEachなどのループ処理をよりシンプルにできます。コードがすごくきれいになるため、プログラマーとしては覚えておきたいもののひとつです。
SelectManyメソッドについて
配列が単純であればLINQSelectメソッドでも大丈夫です。配列に配列を、のようなコレクションは面倒になります。
「平坦化」と呼ばれ、ひとつにすることを簡単にできるのがSelectManyメソッドです。Selectメソッドでは、String.joinメソッドなど、複合して処理しなければなりません。
しかし、SelectManyメソッドの利用で、これを展開できるようになります。
LINQとデータベース言語の関係性について
ざっくりとした見解ですが、データベース以外のデータをSelectメソッドではSQLクエリのような感じで操作できます。SQL知識がない状態では、LINQのメリットや用語が分かりにくいこともあるため、ラムダ式も知っておいた方がいいでしょう。
LINQSelectメソッドは、データベースだけではなくて、オブジェクトの入っている配列や、
「データソース」としているものに、SQLクエリ的にアクセスできることが目的です。さらに、操作がスムーズになります。
LINQのSelectメソッドでできること
Selectメソッドは、コレクション(いわゆる配列)の一つ一つに対するデータ処理を一括して行うのに適しています。同じような処理を行う場合であれば、ForEachメソッドなどよりも、シンプルなコードで記述することが可能です。
配列内の結果を出力できる
ライブラリー化されたLINQのSelectメソッドを使うことで、簡素なコードを書けます。また、メンテナンス性についても向上可能です。
LINQライブラリーの利用には、System.Lingをusing宣言、各メソッドを記述します。LINQの形式では、foreachのカッコ内をラムダ式に記述し、そのうえ内部の条件分岐処理を入れ子にできます。
foreachだけではなくて、LINQメソッドとの併用で、利用の頻度や、書き方なども大きく変わってきます。こういったリストのデータの集まりをLINQは処理をします。
配列内の結果を配列にできる
読みやすさとしては大きなメリットです。ひとつのやりたいことにつき、ひとつのメソッドを呼び出します。
LINQのSelectメソッドではバグも発生しにくいです。これは、ロジックは自分で書く必要がないため、バグが入る余地が少なくなるからです。またLINQの便利さは、クラスを使う時に便利です。
配列内の要素それぞれに、処理と結果を得ることにSelectメソッドを使いましょう。
LINQのSelectメソッドの書き方3選
LINQのSelectメソッドではデータベースだけではなく、同じコレクションや配列にも使えます。他には、XMLデータ、ADO.NETのセットなども利用可能です。
想像するならば、VBからSQL文の発行の文字列は不便ですが、言語に取り込んでみましょう。そうすれば、同じ記述でコレクションにもXMLにも使えるようになります。
LINQプロパイダを使用し、クエリは「From句」始まりで「Select句」で終わるようになっています。
LILQのSelectメソッドでは、問い合わせ先のデータソースの(From n IN XXX)XXXの部分の型にもとづいて、クエリがコンパイルをどのようにするのか、実行されるのかが、決まり、処理の実行をするクラスの種類によって変わってきます。
このようなデータソースが存在する一連のクラス群は「LINQプロパイダ」と呼びます。
LINQのSelectメソッドの書き方1:基本構文の場合
LINQを使って簡潔にするために、ラムダ式を使いましょう。Selectメソッドでは、コレクション要素をすべて処理します。そして、後に別のオブジェクトへ渡します。
LINQの実行で、AnyメソッドやAllを使えば、コレクションの要素の条件を満たしているかが判定できます。
C#で、LINQ to XMLという技術を使えば、HTML、XMLドキュメントも簡単に解析可能ですので、使いこなすことができるようになりましょう。
LINQのSelectメソッドの書き方2:変数がない場合とある場合
LINQでは、クエリを格納する変数(クエリ変数)は常に列挙が可能です。
ステートメントが実行されるときは、クエリ変数を通じて返されませんので、結果が、ワープで反復処理になります。
変数とデータソースのどちらかを変更しないなら、生成は同じ結果です。つまり変数名がXでなければならないという必要もありません。
LINQのSelectメソッドの書き方3:int型で変数を指定する場合
Selectの結果に、さらにSelectをかけることが可能です。int型は本来「from int x」のように書きますが、自動的に型を確定します。また、Select句はクエリ結果に値を指定します。
クエリは、アプリケーションの観点で、元のソースデータの特定の型や構造体は重要でなくソースシーケンスに対して操作を行います。個々の要素は変更せず、サブセットを取得し、新しいシーケンスを生成します。
Selectメソッドのサンプルコード
配列の中身を加工して表示する1 数値計算処理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<br>
using System;<br>
using System.Linq;<br>
namespace TEST2<br>
{<br>
class Test2<br>
{<br>
static void Main()<br>
{<br>
int[] test_var = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};<br>
<br>
var output = test_var.Select(x => x * 5);<br>
Console.WriteLine(""{0}"", string.Join("", "", output));<br>
}<br>
}<br>
}<br>
|
実行結果
1
|
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50
|
このコードでは、配列内の数値を5倍した数値を出力するようにします。
配列の中身を加工して表示する2 型変換
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<br>
using System;<br>
using System.Linq;<br>
namespace TEST3<br>
{<br>
class Test3<br>
{<br>
static void Main()<br>
{<br>
int[] test_var = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};<br>
<br>
var output = test_var.Select( value => value % 4 );<br>
Console.WriteLine(""{0}"", string.Join("","", output));<br>
}<br>
}<br>
}<br>
|
実行結果
1
|
0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2
|
このコードでは、コレクション内のデータ(数値)を4で除した余りを出力しています。
foreach文を使用した例(比較)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<br>
using System;<br>
namespace TEST<br>
{<br>
class Test<br>
{<br>
static void Main()<br>
{<br>
int[] test_var = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};<br>
int out_val;<br>
foreach(int val in test_var){<br>
out_val = val % 4;<br>
Console.WriteLine(""{0}"",out_val);<br>
}<br>
}<br>
}<br>
}<br>
|
実行結果
1
2
3
4
5
6
7
8
9
10
11
12
|
<br>
0<br>
1<br>
2<br>
3<br>
0<br>
1<br>
2<br>
3<br>
0<br>
1<br>
2<br>
|
見かけは「配列の中身を加工して表示する2」と同じになりますが、foreach内で余りを計算する処理を入れる必要があります。
Whereオペレータを使う際のポイントとは
Whereオペレータと組み合わせで使いましょう。条件を満たす要素ならSlectメソッドの引数のように、ラムダ式で記述されます。また、Whereオペレータを使う時は、配列srcの要素より、1より大きい要素のみ、処理を行います。
Whereオペレータでは因数で複数の条件を指定できます。さらに、コレクションの操作をする際には、for文やforeach文で書くよりも、記述の手間を減らすことが可能です。
ラムダ式を引用する
ラムダ式とは、デリゲート型、式ツリー型を作成するために使用する匿名関数で、メソッド内部で定義する書き方になります。小さいメソッドをいちいち定義していては、面倒です。そのため、メソッドをMainメソッド内部で定義してしまえば簡単です。
デリゲートを作るため、クラスメソッドやインスタンスメソッドを定義するのは、とても手間が掛かって読みにくいでしょう。また、匿名関数には2種類ありますが、そのひとつがラムダ式です。
デリゲートとは、C#でメソッドを引数として渡したら返り値として返すのではなく、メソッドを参照するデリゲートを返り値として返します。デリゲートの存在がLINQを支えており、デリゲートの型は自分で作ることが可能です。
複数の条件を指定ができる
自作リストの複数条件を検索する時、まずは、文字列、数値で検索結果のリストをコンソールに表示してみましょう。
And、Orで抽出するか、抽出したあとで整列をリストにする方法かを示します。抽出、検索がほとんど同じで、リストの検索に応用可能です。
linqを使い、自作クラスのリストを複数条件で検索してみて、文字列や数値を検索した結果のリストを整列するには、And、Orの条件で抽出した後、リストを整列します。抽出も検索も同じなので、linqによるリスト操作はリスト検索もできます。
foreach文でSelectメソッドを書いた場合
foreach文は、記述した処理を何回も繰り返して実行します。配列はArray型といいます。引数部分にコールバック関数というfunctonを指定しなければなりません。
しかし、ラムダ式で「アロー関数」を使えば、感覚的に簡単に記述できます。また、Selectメソッドを書いた場合、C#では、繰り返しループを、コレクションのオブジェクトから呼びだし、使い、ラムダ式で処理の記述をします。
- システム
エンジニア - 同じ繰り返し処理なのに、ForEachと比べると確かにコードがシンプルですね。
- プロジェクト
マネージャー - Select単体で条件を付けるのはできない代わりに、コードがきれいになるからプログラマーとしては使い方を覚えておきたいところです。
- システム
エンジニア - 単体でということは、ほかにも別の使い方があるということですか?
- プロジェクト
マネージャー - ほかのLinqメソッドとの組み合わせなどの利用パターンがありますが、それはまた別の機会に紹介しましょう。
コレクションの形式を変換するには最適
Selectメソッドは、コレクションのデータを射影するのに向いています。ネストしたリストを平坦化する場合には、ネストしたリストを平坦化する場合には、SelectManyというメソッドがあります。用途に応じて使い分けていきましょう。
FEnet.NETナビ・.NETコラムは株式会社オープンアップシステムが運営しています。
株式会社オープンアップシステムはこんな会社です
秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
数多くのエンジニアが集まります。
-
スマホアプリから業務系システムまで
スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。
-
充実した研修制度
毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。
-
資格取得を応援
スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。
-
東証プライム上場企業グループ
オープンアップシステムは東証プライム上場「株式会社オープンアップグループ」のグループ企業です。
安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。
株式会社オープンアップシステムに興味を持った方へ
株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。
新着案件New Job
-
開発エンジニア/東京都品川区/【WEB面談可】/在宅ワーク
月給29万~30万円東京都品川区(大崎駅) -
遠隔テストサービス機能改修/JavaScript/東京都港区/【WEB面談可】/テレワーク
月給45万~60万円東京都港区(六本木駅) -
病院内システムの不具合対応、保守/東京都豊島区/【WEB面談可】/テレワーク
月給30万~30万円東京都豊島区(池袋駅) -
開発/JavaScript/東京都豊島区/【WEB面談可】/テレワーク
月給50万~50万円東京都豊島区(大塚駅) -
債権債務システム追加開発/東京都文京区/【WEB面談可】/在宅勤務
月給62万~67万円東京都文京区(後楽園駅) -
PMO/東京都豊島区/【WEB面談可】/在宅勤務
月給55万~55万円東京都豊島区(池袋駅)