C# PR

【C# LINQ】Selectで複数項目を抽出する3つの方法

記事内に商品プロモーションを含む場合があります

こんにちは!

C#でのデータ操作に欠かせないLINQ。その中でも特に便利なSelectメソッドですが、複数の項目を一度に抽出する方法について、詳しく知りたいと思いませんか。

LINQのSelectで、複数のプロパティを抜き出すにはどうすればいいの?
「匿名型」ってよく聞くけど、具体的にどう使うんだろう。
新しいクラスを作って、そこに結果を入れる方法も知りたいな。

C#でLINQを使い始めたばかりのころ、このような疑問を持つことは自然なことです。

この記事では、C# LINQのSelectメソッドを使って、コレクションから複数の項目を抽出するための基本的な方法を、初心者の方にも分かりやすく丁寧に解説します。

この記事は次のような方におすすめです。

この記事はこんな人におすすめ!
  • LINQのSelectメソッドの基本的な使い方を学びたい方。
  • コレクションから特定のデータだけを複数選び出す方法を知りたい方。
  • C#でのデータ加工を効率的に行いたいと考えている開発者。
  • 匿名型やDTOを使ったデータ抽出に興味がある方。
  • LINQの基礎をしっかりと固めたいプログラミング初学者の方。

この記事を読めば、Selectメソッドを使った複数項目の抽出方法が明確に理解でき、実際のコードですぐに応用できる知識が身につきます。LINQの強力な機能を活用して、よりクリーンで読みやすいコードを書けるようになりましょう。

「データの中から必要な情報だけをスマートに取り出したい方」や「LINQの表現力を高めたい方」は、ぜひ最後までお付き合いください。

それでは、順を追って詳しく見ていきましょう!

LINQのSelectメソッドとは何か

まずはじめに、LINQのSelectメソッドがどのような機能を持つのかを確認しておきましょう。

Selectメソッドは、コレクション(例えばリストや配列など)の各要素に対して、何らかの変換処理を行い、その結果からなる新しいコレクションを生成するためのメソッドです。SQLのSELECT句がテーブルから特定の列を取り出すように、LINQのSelectはコレクションから必要なデータを取り出す役割を果たします。

Selectメソッドの基本的な特徴は以下の通りです。

  • コレクションの各要素を一つずつ順番に処理します。
  • 各要素を新しい形式や値に変換します。
  • 元のコレクション自体は変更されません。
  • 変換後の要素で構成される新しいシーケンス(IEnumerable<T>)を返します。

このSelectメソッドを使うことで、元のデータ構造に手を加えることなく、目的に応じたデータだけを柔軟に抽出できます。

Selectで単一の項目を抽出する基本

複数の項目を扱う前に、まずは最も基本的な使い方である、単一の項目を抽出する方法を見てみましょう。

例えば、Userというクラスのリストがあり、各ユーザーのNameプロパティだけを抜き出したい場合、次のように書くことができます。

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

// ユーザー情報を表すクラス
public class User
{
  public int Id { get; set; }
  public string Name { get; set; }
  public int Age { get; set; }
}

public class Program
{
  public static void Main()
  {
    // ユーザーのリストを作成
    var users = new List<User>
    {
      new User { Id = 1, Name = "山田太郎", Age = 25 },
      new User { Id = 2, Name = "佐藤花子", Age = 31 },
      new User { Id = 3, Name = "鈴木一郎", Age = 40 }
    };

    // SelectメソッドでNameプロパティだけを抽出
    var names = users.Select(u => u.Name);

    Console.WriteLine("ユーザー名の一覧:");
    foreach (var name in names)
    {
      Console.WriteLine(name);
    }
  }
}

このコードでは、users.Select(u => u.Name)の部分が核心です。usersリストの各要素(u)から、そのNameプロパティだけを取り出し、namesという新しいコレクションを作成しています。

出力結果は次のようになります。

ユーザー名の一覧:
山田太郎
佐藤花子
鈴木一郎

このように、Selectはコレクション内の各要素から特定のプロパティを簡単に取り出すことができます。

LINQのSelectで複数の項目を抽出する3つの方法

それでは本題に入りましょう。

LINQのSelectメソッドを使って一度に複数の項目を抽出するには、いくつかの方法があります。ここでは、代表的な3つのアプローチ「匿名型」「DTO」「タプル」について、それぞれの特徴と使い方を詳しく解説します。
状況に応じて最適な方法を選ぶことで、コードの可読性や再利用性を高めることが可能です。

方法1:匿名型(Anonymous Type)で手軽に抽出する

「匿名型」は、その名の通り、名前を持たない一時的なクラスを手軽に作成するための機能です。new { ... } という構文で、プロパティ名とその値を指定するだけで、新しいオブジェクトをその場で定義できます。

Selectメソッドと組み合わせることで、必要なプロパティだけを持つ新しいオブジェクトのコレクションを簡単に作ることができます。

先ほどのUserリストから、NameAgeの2つのプロパティを抽出してみましょう。

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

public class User
{
  public int Id { get; set; }
  public string Name { get; set; }
  public int Age { get; set; }
}

public class Program
{
  public static void Main()
  {
    var users = new List<User>
    {
      new User { Id = 1, Name = "山田太郎", Age = 25 },
      new User { Id = 2, Name = "佐藤花子", Age = 31 },
      new User { Id = 3, Name = "鈴木一郎", Age = 40 }
    };

    // 匿名型を使ってNameとAgeを抽出
    var userInfos = users.Select(u => new { u.Name, u.Age });

    Console.WriteLine("ユーザーの情報(名前と年齢):");
    foreach (var info in userInfos)
    {
      Console.WriteLine($"名前: {info.Name}, 年齢: {info.Age}");
    }
  }
}

users.Select(u => new { u.Name, u.Age }) の部分に注目してください。ここでは、各ユーザー u に対して、NameAgeという2つのプロパティを持つ新しい匿名オブジェクトを作成しています。

このコードを実行すると、以下のような結果が得られます。

ユーザーの情報(名前と年齢):
名前: 山田太郎, 年齢: 25
名前: 佐藤花子, 年齢: 31
名前: 鈴木一郎, 年齢: 40

元のUserオブジェクトにあったIdプロパティは含まれず、指定したNameAgeだけを持つ新しいオブジェクトの集まりが作られました。

プロパティに別名をつける

匿名型では、プロパティに新しい名前を付けることもできます。

// 匿名型でプロパティに別名をつける例
var userInfosWithAlias = users.Select(u => new { UserName = u.Name, UserAge = u.Age });

foreach (var info in userInfosWithAlias)
{
  Console.WriteLine($"ユーザー名: {info.UserName}, 年齢: {info.UserAge}");
}

このように 新しいプロパティ名 = 値 の形で指定することで、より分かりやすい名前でデータを扱うことができます。

方法2:DTO(Data Transfer Object)で構造化する

もう一つの方法は、抽出したデータを格納するための新しいクラスをあらかじめ定義しておくやり方です。このような、データを転送するためだけの単純なクラスは、一般的にDTO(Data Transfer Object)と呼ばれます。

この方法は、匿名型と比べて少し手間がかかりますが、メソッドの戻り値として使ったり、別のレイヤーにデータを渡したりする場合に非常に有効です。

まず、NameAgeを保持するためのUserDtoクラスを定義します。

// データを転送するためのクラス(DTO)
public class UserDto
{
  public string Name { get; set; }
  public int Age { get; set; }
}

次に、Selectメソッドの中で、このUserDtoクラスのインスタンスを生成します。

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

public class User
{
  public int Id { get; set; }
  public string Name { get; set; }
  public int Age { get; set; }
}

public class UserDto
{
  public string Name { get; set; }
  public int Age { get; set; }
}

public class Program
{
  public static void Main()
  {
    var users = new List<User>
    {
      new User { Id = 1, Name = "山田太郎", Age = 25 },
      new User { Id = 2, Name = "佐藤花子", Age = 31 },
      new User { Id = 3, Name = "鈴木一郎", Age = 40 }
    };

    // DTOを使ってNameとAgeを抽出
    var userDtos = users.Select(u => new UserDto
    {
      Name = u.Name,
      Age = u.Age
    });

    Console.WriteLine("ユーザーの情報(DTO):");
    foreach (var dto in userDtos)
    {
      Console.WriteLine($"名前: {dto.Name}, 年齢: {dto.Age}");
    }
  }
}

users.Select(u => new UserDto { ... }) の部分で、各ユーザー u の情報を使ってUserDtoの新しいインスタンスを作成しています。

実行結果は匿名型を使った場合と全く同じですが、userDtosIEnumerable<UserDto>という明確な型を持つため、コードの可読性や再利用性が向上します。

方法3:タプル(Tuple)でシンプルにまとめる

3つ目の方法として、「タプル」を利用する方法があります。タプルは、複数の値をひとまとめにして手軽に扱うためのデータ構造です。

特にC# 7.0から導入された「値タプル(ValueTuple)」は、匿名型のように手軽でありながら、DTOのように型情報も保持できるため、両者の中間的な選択肢として非常に優れています。

Selectメソッドと組み合わせることで、シンプルかつ型安全に複数の項目を抽出できます。

// タプルを使ってNameとAgeを抽出する例
var userTuples = users.Select(u => (UserName: u.Name, UserAge: u.Age));

Console.WriteLine("ユーザーの情報(タプル):");
foreach (var item in userTuples)
{
  Console.WriteLine($"名前: {item.UserName}, 年齢: {item.UserAge}");
}

(UserName: u.Name, UserAge: u.Age) の部分がタプルを生成している箇所です。ここでは各要素にUserNameUserAgeという名前を付けており、後から直感的にアクセスできます。

このコードの出力も、前述の2つの方法と全く同じになります。タプルは、メソッド内で完結するものの、少し複雑なデータを扱いたい場合に特に役立ちます。

3つの方法の比較と使い分け

ここまで紹介した3つの方法を、どのような基準で使い分ければ良いのでしょうか。それぞれのメリットをまとめた比較表を見てみましょう。

方法 手軽さ 再利用性 用途の例
匿名型 とても手軽に書けます。 低く、そのメソッド内での利用が基本です。 メソッド内で一度だけ使う一時的なデータ整形に適しています。
DTO 事前にクラス定義が必要で、少し手間がかかります。 高く、プロジェクト全体で再利用できます。 メソッドの戻り値やAPIのレスポンスなど、明確な契約が必要な場面で役立ちます。
タプル 手軽に書けます。 DTOよりは低いですが、メソッドの戻り値としても使えます。 メソッド内で複数の値を返したい場合など、少し複雑な一時的データに適しています。

基本的には、そのデータが「どれくらいの範囲で、どのくらいの期間使われるか」を基準に選ぶと良いでしょう。

キャリア形成/給与還元
ひとつひとつ真摯に向き合う企業
ONE_WEDGE社員募集

株式会社 ONE WEDGEでは、新たな仲間を募集しています!

私たちと一緒に、革新的で充実したキャリアを築きませんか?
当社は、従業員が仕事と私生活のバランスを大切にできるよう、充実した福利厚生を整えています。

  • 完全週休2日制(土日休み)で、祝日や夏季休暇、年末年始休暇もしっかり保証!
  • 様々な休暇制度(有給、慶弔、産前・産後、育児、バースデー休暇、有給6日取得で特別休暇付与)を完備!
  • 従業員の成長と健康を支援するための表彰制度、資格取得支援、健康促進手当など!
  • 生活を支えるテレワーク手当、記事寄稿手当、結婚祝金・出産祝金など、様々な手当を提供!
  • 自己啓発としての書籍購入制度や、メンバー間のコミュニケーションを深める交流費補助!
  • 成果に応じた決算賞与や、リファラル採用手当、AI手当など、頑張りをしっかり評価!
  • ワークライフバランスを重視し、副業もOK!

株式会社 ONE WEDGEでは、一人ひとりの従業員が自己実現できる環境を大切にしています。
共に成長し、刺激を与え合える仲間をお待ちしております。
あなたの能力と熱意を、ぜひ当社で発揮してください。
ご応募お待ちしております!

ホームページ、採用情報は下記ボタンからご確認ください!

応募、ご質問など、お問い合わせフォーム、またはX (旧Twitter)、InstagramのDMでお気軽にご相談ください♪

まとめ

今回は、C#のLINQ Selectメソッドを使って、コレクションから複数の項目を抽出するための3つの基本的なアプローチを解説しました。

  • Selectメソッドはコレクションの各要素を変換して新しいコレクションを作ります。
  • 複数の項目を抽出するには、「匿名型」「DTO」「タプル」の3つの方法があります。
  • 匿名型はnew { ... }構文を使い、その場で一時的なオブジェクトを作るのに適しています。
  • DTOは事前にクラスを定義する方法で、コードの再利用性や可読性が高まります。
  • タプルは、手軽さと型安全性を両立し、匿名型とDTOの中間的な選択肢として優れています。

これらの方法を理解し、状況に応じて適切に使い分けることで、あなたのC#コードはより柔軟で、読みやすく、そして保守しやすいものになります。ぜひ、実際のプロジェクトでこれらのテクニックを活用してみてください。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です