C#のLINQでSelect句を使ったデータ変換の基本!初心者にもわかりやすく解説
生徒
「C#のLINQで、データを別の形に変換する方法ってありますか?」
先生
「はい、LINQのSelect句を使えば、データを簡単に変換できますよ。例えば、リストの中の数値を2倍にしたり、文字列を大文字に変換したりできます。」
生徒
「Select句って、データベースのSELECT文と似ていますか?」
先生
「その通りです!データベースのSELECT文と同じように、欲しいデータを取り出して加工できます。それでは、基本的な使い方を見ていきましょう!」
1. LINQのSelect句とは?
LINQのSelect句は、コレクション(リストや配列など)の中にあるデータを一つひとつ取り出して、別の形に変換するための機能です。例えるなら、工場のベルトコンベアで流れてくる製品を、一つずつ加工して新しい製品に作り替えるようなイメージです。
LINQとは、Language Integrated Query(言語統合クエリ)の略で、C#のプログラムの中で、データベースを操作するような書き方でコレクションを扱える便利な機能です。Select句は、その中でも最も頻繁に使われる基本的な機能の一つです。
Select句を使うことで、元のデータを壊さずに、新しい形式のデータを作り出すことができます。これはデータ変換や射影と呼ばれる処理です。
2. Select句の基本的な使い方
まずは、数値のリストを使った簡単な例から見ていきましょう。以下のコードでは、1から5までの数値が入ったリストを、それぞれ2倍にして新しいリストを作成しています。
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
// 元のリストを作成
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// Select句を使って各要素を2倍にする
var doubledNumbers = numbers.Select(n => n * 2);
// 結果を表示
Console.WriteLine("元のリスト:");
foreach (var num in numbers)
{
Console.Write(num + " ");
}
Console.WriteLine("\n2倍にしたリスト:");
foreach (var num in doubledNumbers)
{
Console.Write(num + " ");
}
}
}
実行結果:
元のリスト:
1 2 3 4 5
2倍にしたリスト:
2 4 6 8 10
このコードでは、Select(n => n * 2)という部分が重要です。n => n * 2はラムダ式と呼ばれるもので、「nという値を受け取って、それを2倍にして返す」という処理を表しています。矢印(=>)の左側が入力、右側が出力だと考えてください。
3. 文字列データの変換
数値だけでなく、文字列のデータも変換できます。次の例では、果物の名前のリストをすべて大文字に変換しています。
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
// 果物のリストを作成
List<string> fruits = new List<string> { "apple", "banana", "orange" };
// Select句を使って大文字に変換
var upperFruits = fruits.Select(f => f.ToUpper());
// 結果を表示
Console.WriteLine("元のリスト:");
foreach (var fruit in fruits)
{
Console.WriteLine(fruit);
}
Console.WriteLine("\n大文字に変換:");
foreach (var fruit in upperFruits)
{
Console.WriteLine(fruit);
}
}
}
実行結果:
元のリスト:
apple
banana
orange
大文字に変換:
APPLE
BANANA
ORANGE
ここでは、ToUpper()というメソッドを使って、各文字列を大文字に変換しています。Select(f => f.ToUpper())の部分で、リストの中の各要素(f)に対してToUpper()を実行し、その結果を新しいリストとして作成しています。
4. オブジェクトの特定のプロパティだけを取り出す
実際の開発では、クラスで定義されたオブジェクトのリストから、特定の情報だけを取り出すことがよくあります。次の例では、商品情報から商品名だけを取り出しています。
using System;
using System.Collections.Generic;
using System.Linq;
// 商品クラスの定義
class Product
{
public string Name { get; set; }
public int Price { get; set; }
}
class Program
{
static void Main()
{
// 商品リストを作成
List<Product> products = new List<Product>
{
new Product { Name = "ノートPC", Price = 80000 },
new Product { Name = "マウス", Price = 2000 },
new Product { Name = "キーボード", Price = 5000 }
};
// Select句で商品名だけを取り出す
var productNames = products.Select(p => p.Name);
// 結果を表示
Console.WriteLine("商品名一覧:");
foreach (var name in productNames)
{
Console.WriteLine(name);
}
}
}
実行結果:
商品名一覧:
ノートPC
マウス
キーボード
この例では、ProductクラスにName(商品名)とPrice(価格)という2つのプロパティ(データの属性)がありますが、Select(p => p.Name)で商品名だけを取り出しています。プロパティとは、オブジェクトが持っているデータのことで、ドット(.)でアクセスできます。
5. 新しい形式のオブジェクトに変換する
Select句の強力な機能の一つは、元のデータから全く新しい形式のデータを作り出せることです。これを匿名型を使って実現してみましょう。
using System;
using System.Collections.Generic;
using System.Linq;
class Product
{
public string Name { get; set; }
public int Price { get; set; }
}
class Program
{
static void Main()
{
List<Product> products = new List<Product>
{
new Product { Name = "ノートPC", Price = 80000 },
new Product { Name = "マウス", Price = 2000 },
new Product { Name = "キーボード", Price = 5000 }
};
// Select句で新しい形式に変換(税込価格を追加)
var productsWithTax = products.Select(p => new
{
ProductName = p.Name,
PriceWithTax = p.Price * 1.1
});
// 結果を表示
Console.WriteLine("商品名と税込価格:");
foreach (var item in productsWithTax)
{
Console.WriteLine($"{item.ProductName}: {item.PriceWithTax}円");
}
}
}
実行結果:
商品名と税込価格:
ノートPC: 88000円
マウス: 2200円
キーボード: 5500円
この例では、new { }という書き方で匿名型のオブジェクトを作成しています。匿名型とは、その場で一時的に使うためだけの型で、クラス定義を書かなくても新しいオブジェクトを作れる便利な機能です。ここでは、商品名と税込価格という新しい情報の組み合わせを作り出しています。
6. クエリ構文とメソッド構文
LINQには、クエリ構文とメソッド構文という2つの書き方があります。これまで紹介してきたのはメソッド構文ですが、クエリ構文でも同じことができます。
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// メソッド構文
var doubled1 = numbers.Select(n => n * 2);
// クエリ構文
var doubled2 = from n in numbers
select n * 2;
Console.WriteLine("メソッド構文:");
foreach (var num in doubled1)
{
Console.Write(num + " ");
}
Console.WriteLine("\nクエリ構文:");
foreach (var num in doubled2)
{
Console.Write(num + " ");
}
}
}
実行結果:
メソッド構文:
2 4 6 8 10
クエリ構文:
2 4 6 8 10
クエリ構文は、SQLのような書き方で直感的ですが、メソッド構文の方がより強力で柔軟な処理ができます。どちらを使っても結果は同じですので、自分の好みや状況に応じて選択してください。初心者の方には、まずメソッド構文に慣れることをおすすめします。
7. Select句を使う際の注意点
Select句を使う際には、いくつかの注意点があります。まず、Select句は遅延実行という特性を持っています。これは、Select句を書いた時点では実際の変換処理は行われず、結果を使おうとしたとき(foreachで回すときなど)に初めて実行されるということです。
また、Select句で作られた結果はIEnumerable型という特殊な型になります。これをリストとして扱いたい場合は、ToList()メソッドを使ってリストに変換できます。
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// Select句の結果をリストに変換
List<int> doubledList = numbers.Select(n => n * 2).ToList();
Console.WriteLine("リストとして保存:");
foreach (var num in doubledList)
{
Console.Write(num + " ");
}
}
}
実行結果:
リストとして保存:
2 4 6 8 10
ToList()を使うことで、その時点で処理が実行され、結果がリストとして確定します。これにより、何度も同じ結果を使う場合でも、処理が一度だけで済むようになります。