知って得するC# LINQ to Objects編

Post on 18-Dec-2014

3.406 views 2 download

description

 

Transcript of 知って得するC# LINQ to Objects編

知って得する C# LINQ to Objects編

株式会社ハ・ン・ド

プログラマ

馬場翔太

http://baba-s.hatenablog.com/

スライド内容

1. LINQ to Objectsとは

2. LINQ to Objectsの使用例

LINQ to Objectsとは

コレクションを扱うための新しい方法

for文やforeach文を使わず下記の様な処理が行えます

• 条件を満たす要素の数を取得

• 条件を満たす要素を抽出

• 条件を満たす最初の要素を取得

• 昇順にソート

• etc.

LINQ to Objectsを使うために必要なこと

using System.Linq;

この一行をソースコードの先頭に追加するだけです

「using System.Linq;」を追加すると…

配列やリストで多くの拡張メソッドが使用可能になります

• Count

• Where

• First

• OrderBy

• etc.

次のスライドから順番に紹介していきます

LINQ to Objectsの使用例

// 兵士の数を取得します

var result = 0;

foreach (var character in characters)

{

if (character.Job == "Soldier")

{

result++;

}

}

条件を満たす要素の数を取得する

従来のコーディング

// 兵士の数を取得します

var result = characters.Count(c => c.Job == "Soldier");

条件を満たす要素の数を取得する

Countメソッドを使用

// 兵士のみ取得します

var result = new List<Character>();

foreach (var character in characters)

{

if (character.Job == "Soldier")

{

result.Add(character);

}

}

条件を満たす要素を抽出する

従来のコーディング

// 兵士のみ取得します

var result = characters.Where(c => c.Job == "Soldier");

条件を満たす要素を抽出する

Whereメソッドを使用

// すべてのキャラクターから名前だけ取得します

var result = new List<string>();

foreach (var character in characters)

{

result.Add(character.Name);

}

要素を射影する

従来のコーディング

// すべてのキャラクターから名前だけ取得します

var result = characters.Select(c => c.Name);

要素を射影する

Selectメソッドを使用

// 全員が兵士かどうかを判断します

var result = true;

foreach (var character in characters)

{

if (character.Job != "Soldier")

{

result = false;

break;

}

}

すべての要素が条件を満たしているか

従来のコーディング

// 全員が兵士かどうかを判断します

var result = characters.All(c => c.Job == "Soldier");

すべての要素が条件を満たしているか

Allメソッドを使用

// 兵士が存在するかどうかを取得します

var result = false;

foreach (var character in characters)

{

if (character.Job == "Soldier")

{

result = true;

break;

}

}

いずれかの要素が条件を満たしているか

従来のコーディング

// 兵士が存在するかどうかを取得します

var result = characters.Any(c => c.Job == "Soldier");

いずれかの要素が条件を満たしているか

Anyメソッドを使用

// 先頭の兵士を取得します

Character result = null;

foreach (var character in characters)

{

if (character.Job == "Soldier")

{

result = character;

break;

}

}

条件を満たす最初の要素を取得する

従来のコーディング

// 先頭の兵士を取得します

var result = characters.First(c => c.Job == "Soldier");

条件を満たす最初の要素を取得する

Firstメソッドを使用

(条件を満たす要素がない場合は例外になります)

// 先頭の兵士を取得します

var result = characters.FirstOrDefault(c => c.Job == "Soldier");

条件を満たす最初の要素を取得する

FirstOrDefaultメソッドを使用

(条件を満たす要素がない場合は既定値を返します)

// 末尾の兵士を取得します

Character result = null;

for (int i = characters.Length - 1; i >= 0; i--)

{

if (characters[i].Job == "Soldier")

{

result = characters[i];

break;

}

}

条件を満たす最後の要素を取得する

従来のコーディング

// 末尾の兵士を取得します

var result = characters.Last(c => c.Job == "Soldier");

条件を満たす最後の要素を取得する

Lastメソッドを使用

(条件を満たす要素がない場合は例外になります)

// 末尾の兵士を取得します

var result = characters.LastOrDefault(c => c.Job == "Soldier");

条件を満たす最後の要素を取得する

LastOrDefaultメソッドを使用

(条件を満たす要素がない場合は既定値を返します)

var result = characters[characters.Length - 1];

最後の要素を取得する

従来のコーディング

Lastメソッドを使用

var result = characters.Last();

// すべてのキャラクターの中で

// 最も大きな力のパラメータを取得します

var result = 0;

foreach (var character in characters)

{

if (result < character.Power)

{

result = character.Power;

}

}

最大値を取得する

従来のコーディング

// すべてのキャラクターの中で

// 最も大きな力のパラメータを取得します

var result = characters.Max(c => c.Power);

最大値を取得する

Maxメソッドを使用

// すべてのキャラクターの中で

// 最も小さな力のパラメータを取得します

var result = int.MaxValue;

foreach (var character in characters)

{

if (character.Power < result)

{

result = character.Power;

}

}

最小値を取得する

従来のコーディング

// すべてのキャラクターの中で

// 最も小さな力のパラメータを取得します

var result = characters.Min(c => c.Power);

最小値を取得する

Minメソッドを使用

// 最も大きな力を持つキャラクターを取得します

int max = characters.Max(c => c.Power);

var result = characters.First(c => c.Power == max);

最大値を持つ要素を取得する

MaxメソッドとFirstメソッドを使用

// 最も大きな力を持つキャラクターをすべて取得します

int max = characters.Max(c => c.Power);

var result = characters.Where(c => c.Power == max);

最大値を持つ要素をすべて取得する

MaxメソッドとWhereメソッドを使用

// アイテムの購入金額を取得します

var result = 0;

foreach (var item in items)

{

result += item.Price;

}

合計値を取得する

従来のコーディング

// アイテムの購入金額を取得します

var result = items.Sum(c => c.Price);

合計値を取得する

Sumメソッドを使用

// アイテムの平均金額を取得します

var result = 0;

foreach (var item in items)

{

result += item.Price;

}

result /= items.Count;

平均値を取得する

従来のコーディング

// アイテムの平均金額を取得します

var result = items.Average(c => c.Price);

平均値を取得する

Averageメソッドを使用

// 錬金術士のみ錬金術を使います

foreach (var character in characters)

{

var result = character as Alchemist;

if (result != null)

{

result.Alchemy();

}

}

指定された型に一致する要素を抽出する

従来のコーディング

// 錬金術士のみ錬金術を使います

foreach (var result in characters.OfType<Alchemist>())

{

result.Alchemy();

}

指定された型に一致する要素を抽出する

OfTypeメソッドを使用

// すべてのフラグをONで初期化します

bool[] flags = new bool[100];

for (int i = 0; i < flags.Length; i++)

{

flags[i] = true;

}

配列を規定値で初期化する

従来のコーディング

// すべてのフラグをONで初期化します

bool[] flags = Enumerable.Repeat(true, 100).ToArray();

配列を規定値で初期化する

Repeatメソッドを使用

//最新の10件のプレゼントの一覧を取得します

var result = new List<Present>();

for (int i = 0; i < 10; i++)

{

result.Add(presents[i]);

}

指定された数の要素を取得する

従来のコーディング

//最新の10件のプレゼントの一覧を取得します

var result = presents.Take(10);

指定された数の要素を取得する

Takeメソッドを使用

// 11件目以降のプレゼントの一覧を取得します

var result = new List<Present>();

for (int i = 10; i < presents.Length; i++)

{

result.Add(presents[i]);

}

指定された数の要素を読み飛ばす

従来のコーディング

// 11件目以降のプレゼントの一覧を取得します

var result = presents.Skip(10);

指定された数の要素を読み飛ばす

Skipメソッドを使用

// 指定されたページに表示する

// プレゼントの一覧を取得します

var result = presents.Skip(page * 10).Take(10);

ページャーの機能を実装する

SkipメソッドとTakeメソッドを使用

// 価格が安い順にアイテムを取得します

var result = items.OrderBy(c => c.Price);

昇順にソートする

OrderByメソッドを使用

// 価格が安い順にアイテムを取得します

var result = items.OrderByDescending(c => c.Price);

降順にソートする

OrderByDescendingメソッドを使用

// アイテムの順番を逆転させます

var result = items.Reverse();

逆順にする

Reverseメソッドを使用

// 名前の重複を取り除きます

var result = names.Distinct();

重複を取り除く

Distinctメソッドを使用

まとめ

LINQ to Objectsを使用すると…

ソースコードを簡潔に記述できます

• for文が減る

• foreach文が減る

• if文が減る

• 変数が減る

ありがとうございました