いろいろ備忘録日記

主に .NET と Python絡みのメモを公開しています。

Linq入門記-48 (LINQ To Object, First, Last, Single)

今回は、First拡張メソッドとLast拡張メソッド、それとSingle拡張メソッドについてです。
それぞれ、シーケンスの中から特定の一つを抽出してくれるメソッドです。


Firstは、最初の要素を返してくれます。
Lastは、最後の要素を返してくれます。
Singleは、Firstと似ていますが要素が複数あると例外が発生します。


上記のメソッドは、どれも引数にpredicateを受け取るオーバーロードが存在します。
なので、条件に合致した中の最初の要素、最後の要素、唯一の要素を取得することも出来ます。


書式は以下の通り。

public static TSource First<TSource>(
	this IEnumerable<TSource> source
)

public static TSource First<TSource>(
	this IEnumerable<TSource> source,
	Func<TSource, bool> predicate
)

public static TSource Last<TSource>(
	this IEnumerable<TSource> source
)

public static TSource Last<TSource>(
	this IEnumerable<TSource> source,
	Func<TSource, bool> predicate
)

public static TSource Single<TSource>(
	this IEnumerable<TSource> source
)

public static TSource Single<TSource>(
	this IEnumerable<TSource> source,
	Func<TSource, bool> predicate
)


以下、サンプルです。

    #region LinqSamples-45
    public class LinqSamples45 : IExecutable
    {
        public void Execute()
        {
            var languages = new string[] { "csharp", "visualbasic", "java", "python", "ruby", "php", "c++" };
            
            //
            // First拡張メソッドは、シーケンスの最初の要素を返すメソッド。
            //
            // predicateを指定した場合は、その条件に合致する最初の要素が返る。
            //
            Console.WriteLine("============ First ============");
            Console.WriteLine(languages.First());
            Console.WriteLine(languages.First(item => item.StartsWith("v")));
            
            //
            // Last拡張メソッドは、シーケンスの最後の要素を返すメソッド。
            //
            // predicateを指定した場合は、その条件に合致する最後の要素が返る。
            //
            Console.WriteLine("============ Last ============");
            Console.WriteLine(languages.Last());
            Console.WriteLine(languages.Last(item => item.StartsWith("p")));
            
            //
            // Single拡張メソッドは、シーケンスの唯一の要素を返すメソッド。
            //
            // Singleを利用する場合、対象となるシーケンスには要素が一つだけ
            // でないといけない。複数の要素が存在する場合例外が発生する。
            //
            // また、空のシーケンスに対してSingleを呼ぶと例外が発生する。
            //
            // predicateを指定した場合は、その条件に合致するシーケンスの唯一の
            // 要素が返される。この場合も、結果のシーケンスには要素が一つだけの
            // 状態である必要がある。条件に合致する要素が複数であると例外が発生する、
            //
            Console.WriteLine("============ Single ============");
            var onlyOne = new string[] { "csharp" };            
            Console.WriteLine(onlyOne.Single());
            
            try
            {
                languages.Single();
            }
            catch
            {
                Console.WriteLine("複数の要素が存在する状態でSingleを呼ぶと例外が発生する。");
            }
            
            Console.WriteLine(languages.Single(item => item.EndsWith("y")));
            
            try
            {
                languages.Single(item => item.StartsWith("p"));
            }
            catch
            {
                Console.WriteLine("条件に合致する要素が複数存在する場合例外が発生する。");
            }
        }
    }
    #endregion


実行結果は以下の通りです。

  ============ First ============
  csharp
  visualbasic
  ============ Last ============
  c++
  php
  ============ Single ============
  csharp
  複数の要素が存在する状態でSingleを呼ぶと例外が発生する。
  ruby
  条件に合致する要素が複数存在する場合例外が発生する。

================================
過去の記事については、以下のページからご参照下さい。