MADOCHAN BLOG

強いプログラマーを目指す30代のブログ



C#初心者がListの要素を検索するFindメソッドを使いこなす方法

こんにちは!C#エンジニアの窓(@madochanblog)です。

皆さんはC#でListを使っているとき、自分の欲しい要素だけを検索して取得したい!と思ったことはありませんか?

例えば、リストの中から完全一致でヒットする値を取得したい場合や、部分一致で値を取得したい場合もあるのではないでしょうか。

Findメソッド、FindAllメソッドなど検索メソッドを使うと、簡単に検索と取得ができるのです。

ただ、検索メソッドを使いこなそうとすると・・・「ラムダ式」と呼ばれる書き方が必要となります。C#初心者の方にとって、はラムダ式って何?と思う方がほとんどだと思います。

そこで今回は、「ラムダ式の書き方、検索メソッドによるList要素の検索・取得方法」について説明していきます!

検索メソッドに必要なラムダ式とは?

まず、検索メソッドに必要となるラムダ式について解説をします。

ラムダ式とは?

ラムダ式は、メソッドを簡易的に表現したものです。

下記に、通常のメソッドとラムダ式で書き換えたメソッドを示します。

// 通常のメソッド(Addメソッド)
public int Add(int a, int b)
{
  return a + b;
}

// ラムダ式で書き換えたAddメソッド
(int a, int b) => { return a + b; }

ラムダ式は=>を用いて表されます。=>の左辺と右辺では、それぞれ置くものが決まっているんです。

=>の左辺:引数    
=>の右辺:処理の内容

例の場合、Addメソッドの引数であるint a, int bが左辺に、処理の内容であるreturn a + b;が右辺に置かれています。
また、メソッド名が省略されていることがわかります。

ラムダ式を用いて簡易的にメソッドを書くことで、他のメソッドの引数の中にメソッドを入れることができます。

Listの要素を検索して取得するメソッドの引数には、検索条件となる処理を入力する必要があるのです。 そのため検索メソッドの検索条件の指定には、ラムダ式を用いることになります。

ラムダ式についてもっと詳しく知りたい方は、こちらの記事がわかりやすいので、ぜひ参考にしてください。

C# 今更ですが、ラムダ式 - Qiita

検索メソッドの検索条件にラムダ式を使ってみる

実際に、検索メソッドの検索条件にラムダ式を用いたコードを見てみます。

下記は、検索メソッドの1つであるFindメソッドの引数にラムダ式で、検索条件を書いたものです。

using System;
using System.Collections.Generic;

namespace Test
{
    class ListFind
    {
        static void Main(string[] args)
        {
            var fruits = new List<string> { "りんご", "バナナ", "いちご", "なし", "みかん" };

            // fruitsから「い」で始まる要素を検索して取得する
            var result = fruits.Find((string x) => { return x.StartsWith("い"); });

            Console.WriteLine(result);
        }
    }
}
いちご

StartsWithメソッドは引数で指定した文字列から始まる文字を取得します。
Findメソッドの引数の中に「fruitsの値をstring xで受け取って、「い」で始まる要素を返す」という検索条件がラムダ式で書かれています。検索条件通り、「い」で始まる「いちご」が出力されています。

このように、検索条件はラムダ式を用いて書かれます。

C#のListから要素を検索するメソッドの使い方

次に、Listから要素を検索するメソッドの使い方を解説していきます。

Listから要素を検索するメソッドはいくつかあります。ここではFindメソッド、FindAllメソッド、FindIndexメソッド3つを解説します。

これら3つのメソッドは検索対象の数得られる検索結果によって使う場面が決められます。

検索する対象が1件のとき:Findメソッド

Listの要素の中で1件のみ検索して取得したいときは、Findメソッドを使います。

using System;
using System.Collections.Generic;

namespace Test
{
    class ListFind
    {
        static void Main(string[] args)
        {
            var fruits = new List<string> { "りんご", "バナナ", "いちご", "なし", "みかん", "いちじく" };

            // fruitsから「い」で始まる要素を検索して取得する
            var result1 = fruits.Find((string x) => { return x.StartsWith("い"); });

            // fruitsから「す」で始まる要素を検索して取得する
            var result2 = fruits.Find((string x) => { return x.StartsWith("す"); });

            Console.WriteLine("result1: {0}", result1);
            Console.WriteLine("result2: {0}", result2);
        }
    }
}
result1: いちご
result2:  

例の場合、「い」で始まる要素を検索して「いちご」と取得しています。また、「す」で始まる要素はfruitsのListの中には無いので、何も取得されていません。

このようにFindメソッドでは、指定した文字列等に該当する要素が取得できます。

Listの中に複数同じ要素がある場合は、前から検索してはじめに出てきた対象を取得します。そのため「い」で始まる要素は「いちご」のほかに「いちじく」もありますが、「いちご」のみ表示されています。

「いちご」も「いちじく」も全て取得したい場合は、次のFindAllメソッドを用います。

検索する対象が複数のとき:FindAllメソッド

Listの要素の中で複数検索したいときは、FindAllメソッドを使います。

using System;
using System.Collections.Generic;

namespace Test
{
    class ListFind
    {
        static void Main(string[] args)
        {
            var fruits = new List<string> { "りんご", "バナナ", "いちご", "なし", "みかん", "いちじく" };

            // fruitsから「い」で始まる要素を検索してすべて取得する
            var results = fruits.FindAll((string x) => { return x.StartsWith("す"); });

            foreach (var result in results)
            {
               Console.WriteLine(result);
            }
        }
    }
}
いちご
いちじく

このようにFindAllメソッドを用いると、指定した文字列等に該当する要素がすべて取得できます。

検索する対象がListの何番目にあるか知りたいとき:FindIndexメソッド

Listの中で何番目に要素があるのか知りたいときは、FindIndexメソッドを使います。

using System;
using System.Collections.Generic;

namespace Test
{
    class ListFind
    {
        static void Main(string[] args)
        {
            var fruits = new List<string> { "りんご", "バナナ", "いちご", "なし", "みかん", "いちじく" };

            // fruitsから「い」で始まる要素が何番目にあるかを調べる
            var result = fruits.FindIndex((string x) => { return x.StartsWith("い"); });

            Console.WriteLine(result);
        }
    }
}
2

Listの中身は前から0、1、2…と数えます。そして「い」で始まる要素の「いちご」は2番目にあるので、「2」と取得されます。

FindIndexメソッドもFindメソッドと同じように、前から検索をしてはじめて検索条件に該当する要素が、何番目にあるかを取得します。

もし後ろから検索した時に最初に見つけた要素が何番目にあるかを知りたいときには、FindLastIndexメソッドを用います。

using System;
using System.Collections.Generic;

namespace Test
{
    class ListFind
    {
        static void Main(string[] args)
        {
            var fruits = new List<string> { "りんご", "バナナ", "いちご", "なし", "みかん", "いちじく" };

            // fruitsから「い」で始まる要素が何番目にあるかを調べる
            var result = fruits.FindLastIndex((string x) => { return x.StartsWith("い"); });

            Console.WriteLine(result);
        }
    }
}
5

後ろから検索していくと、「い」で始まる要素は「いちじく」が最初に該当します。「いちじく」はListの5番目にある要素なので、「5」と出力されます。

検索メソッド一覧表

このように、検索メソッドは対象の数と得られる検索結果によって使う場面が分けられます。

以下にメソッドと使用する場面をまとめておきますので、どの検索メソッドを用いるか迷った時は参考にして下さい。

メソッド 使用する場面
Find 検索する対象が1件のとき
FindAll 検索する対象が複数のとき
FindIndex 前から検索して、検索対象がListの何番目にあるか知りたいとき
FindLastIndex 後ろから検索して、検索対象がListの何番目にあるか知りたいとき

検索条件に使えるメソッド

ここまで、指定した文字列から始まる要素を探すためのStartsWithメソッドを例にあげていました。
ただ、StartsWithメソッド以外にも、検索条件に使うと便利なメソッドがあります。

その中でも特に、使える汎用性が高いメソッドをご紹介していきますね。

指定した文字列と等しい値を検索するEqualsメソッド

Equalsメソッドは、指定した文字列と等しい要素を検索したいときに用います。

using System;
using System.Collections.Generic;

namespace Test
{
    class ListFind
    {
        static void Main(string[] args)
        {
            var cake = new List<string> { "チョコレートケーキ", "いちごのショートケーキ", "バナナチョコレートケーキ", "チーズケーキ", "抹茶ケーキ" };

            // cakeの要素で「チョコレートケーキ」は何番目にあるかを調べる
            var result = cake.FindIndex((string x) => { return x.Equals("チョコレートケーキ"); });

            Console.WriteLine(result);
        }
    }
}
0

例の場合「チョコレートケーキ」という文字列と完全に一致する要素を検索し、Listの何番目にあるかを取得しています。

指定した文字列を含む値を検索するContainsメソッド

StartsWithメソッドは、指定した文字列で始まる要素を取得するものでした。

Containsメソッドでは、文字列を含む要素を取得するという条件を設定することが可能です。

using System;
using System.Collections.Generic;

namespace Test
{
    class ListFind
    {
        static void Main(string[] args)
        {
            var cake = new List<string> { "チョコレートケーキ", "いちごのショートケーキ", "バナナチョコレートケーキ", "チーズケーキ", "抹茶ケーキ" };

            // cakeから「チョコレート」を含む要素を検索してすべて取得する
            var results = cake.FindAll((string x) => { return x.Contains("チョコレート"); });

            foreach (var result in results)
            {
                Console.WriteLine(result);
            }
        }
    }
}
チョコレートケーキ
バナナチョコレートケーキ

「チョコレート」で始まる要素だけでなく、「チョコレート」が含まれる要素も検索・取得されています。

このように様々なメソッドを用いることで、色々な検索の仕方ができます。

まとめ

今回は、検索条件を設定するラムダ式、検索メソッドの種類や使い方、検索条件に用いられるメソッドについて解説を説明してきました。
検索メソッドを用いると、Listの中の値を自由自在に取り出せるのでとても便利です。

ぜひ使ってみてくださいね!