前回のLINQ to Objects 備忘録2に続いて備忘録を掲載します。今回はRange,Repeat,Empty,Any,All,Contains,OfType,Castを扱います。データはLINQ to Objects 備忘録1で作成したデータを使用します。

確認環境は.NET 3.5, 開発環境はVisual Studio 2008 Professionalです。

今回取り扱っているクエリ式,拡張メソッド

クエリ式,拡張メソッド 簡単な説明
Range,Repeat,Empty拡張メソッド 繰り返しデータの作成、要素が空の集合の作成を行います。
Any,All,Contains拡張メソッド 限量詞演算を行います。
Take,TakeWhile,Skip,SkipWhile拡張メソッド 指定した位置もしくは指定した条件以降の要素の集合を作成します。
OfType,Cast拡張メソッド 集合の要素に対してキャスト演算を行います。

1.LINQクエリメモ

1.1 Range,Repeat,Empty拡張メソッド

Rangeメソッドを使用すると、指定した数から始まる指定個数分のIEnumerable<Int32>型のオブジェクトを取得できます。

var query = Enumerable.Range(10, 4);

foreach (var item in query)
{
     Console.WriteLine(item.ToString());
}

実行結果は次のようになります。

10
11
12
13

Repeatメソッドを使用すると、引数で指定したオブジェクトを指定分複製します。(参照型の場合コピーされるわけではありません。)

var categories = InitializeData();
var query = Enumerable.Repeat((from c in categories
                               where c.ID > 3
                               select c), 2).SelectMany(c => c);
foreach (var item in query)
{
     Console.WriteLine(item.ToString());
}

実行結果は次のようになります。

Category:ID=4, Name=CS
  Article:ID=6, Title=SqlArticle1, ReleaseDate=2008/10/03, ArticleType=Memo

Category:ID=4, Name=CS
  Article:ID=6, Title=SqlArticle1, ReleaseDate=2008/10/03, ArticleType=Memo

Emptyメソッドを使用すると、型引数で指定した要素数が0の集合を作成します。

IEnumerable<Article> article = Enumerable.Empty<Article>();
Console.WriteLine(article.Count());

実行結果は次のようになります。

0

1.2 限量詞Any,All,Contains拡張メソッド

集合の中で、要素が含まれている、指定した述部に該当する要素が存在する場合にTrueを返す拡張メソッドがAnyです。パラメータを指定しない場合は、要素数が0の場合にFalse,1以上の場合はTrueを返します。 述部をパラメータで指定した場合は、述部がTrueの要素が1つ以上含まれていればTrueを返します。

var categories = InitializeData();
Console.WriteLine(categories.Any());
Console.WriteLine(categories.Any(c => c.ID == 3));

IEnumerable<Category> category = Enumerable.Empty<Category>();
Console.WriteLine(category.Any());

実行結果は次のようになります。

True
True
False

All拡張メソッドは、集合のすべての要素が、指定した条件に該当する場合にTrueを返します。

var categories = InitializeData();
Console.WriteLine(categories.All(c=> c.ID > 3));
Console.WriteLine(categories.Any(c => c.ID > 0));

IEnumerable<Category> category = Enumerable.Empty<Category>();
Console.WriteLine(category.All(c=> c.ID > 3));

実行結果は次のようになります。

False
True
True

Contains拡張メソッドは集合内の特定の項目が含まれているかを返します。比較オペレータをカスタムする場合はIEqualityComparer<T>をオーバーロード版のContainsに渡します。集合がICollection<T>を実装している場合は、Containsメソッドを呼び出します。そうではない場合、 要素の中で引数で指定された項目が含まれているかを検査します。比較処理に、IEqualityComparer<T>がメソッドの引数に指定されていない場合はEqualityComparer<T>.Defaultが使用されます。

var query = Enumerable.Range(10, 4);
Console.WriteLine(query.Contains(11));
Console.WriteLine(query.Contains(9));

実行結果は次のようになります。

True
False

1.3 パーティショニングオペレータTake,TakeWhile,Skip,SkipWhile拡張メソッド

Take拡張メソッドは先頭から指定した要素数分取り出した新しいリストを取得します。

var categories = InitializeData();
var query = categories.Take(2);

foreach (var item in query)
{
   Console.WriteLine(item.ToString());
}

 実行結果は次のようになります。

Category:ID=1, Name=CS
  Article:ID=1, Title=CSArticle1, ReleaseDate=2004/01/01, ArticleType=Code
  Article:ID=2, Title=CSArticle2, ReleaseDate=2004/02/01, ArticleType=Memo

Category:ID=2, Name=ASP
  Article:ID=3, Title=CSArticle1, ReleaseDate=2004/01/01, ArticleType=Code
  Article:ID=4, Title=AspArticle1, ReleaseDate=2002/12/21, ArticleType=Memo

TakeWhile拡張メソッドは指定した要素数ではなく、述部で指定した条件がFalseになるまでの要素を含むリストを取得します。

var categories = InitializeData();
var query = categories.TakeWhile(c => c.ID < 3);

foreach (var item in query)
{
    Console.WriteLine(item.ToString());
}

実行結果は次のようになります。

Category:ID=1, Name=CS
  Article:ID=1, Title=CSArticle1, ReleaseDate=2004/01/01, ArticleType=Code
  Article:ID=2, Title=CSArticle2, ReleaseDate=2004/02/01, ArticleType=Memo

Category:ID=2, Name=ASP
  Article:ID=3, Title=CSArticle1, ReleaseDate=2004/01/01, ArticleType=Code
  Article:ID=4, Title=AspArticle1, ReleaseDate=2002/12/21, ArticleType=Memo

Skip拡張メソッドは先頭から指定した要素数を除いた要素からなるリストを取得します。

var categories = InitializeData();
var query = categories.Skip(2);

foreach (var item in query)
{
    Console.WriteLine(item.ToString());
}

実行結果は次のようになります。

Category:ID=3, Name=SQL
  Article:ID=5, Title=SqlArticle1, ReleaseDate=2006/02/03, ArticleType=Code

Category:ID=4, Name=CS
  Article:ID=6, Title=SqlArticle1, ReleaseDate=2008/10/03, ArticleType=Memo

SkipWhile拡張メソッドは指定した要素数ではなく、述部で指定した条件がFalseになるまでの要素を除くリストを取得します。

var categories = InitializeData();
var query = categories.SkipWhile(c => c.ID < 3);

foreach (var item in query)
{
    Console.WriteLine(item.ToString());
}

実行結果は次のようになります。

Category:ID=3, Name=SQL
  Article:ID=5, Title=SqlArticle1, ReleaseDate=2006/02/03, ArticleType=Code

Category:ID=4, Name=CS
  Article:ID=6, Title=SqlArticle1, ReleaseDate=2008/10/03, ArticleType=Memo

1.4 キャスト拡張メソッドOfType,Cast

OfType拡張メソッドは集合の中で、型引数で指定した型の要素からなる集合を作成します。集合が複数の型の要素からなる場合に使用します。

var v1 = new object[] { 1, "test", 3.3, 4m, "test2" };
var query = v1.OfType<string>();
foreach (var item in query)
{
    Console.WriteLine(item);
}

実行結果は次のようになります。

test
test2

Cast拡張メソッドは集合のすべての要素を型引数で指定した型にキャストします。キャストに失敗した場合、InvalidCastExceptionがスローされます。

IEnumerable<int> v1 = new int[] { 1, 2, 3 };
IEnumerable<double> result = v1.Cast<double>();
foreach (var item in result)
{
    Console.WriteLine(item);
}

実行結果は次のようになります。

1
2
3

今回のサンプルの掲載は以上です。

次回はLinq To Objetsの備忘録の最終回、Linq To Objects 備忘録4を掲載します。要素演算、変換演算を掲載します。