c# linq ~深く知って、使いまくろう~

50

Upload: fujio-kojima

Post on 16-Jul-2015

170 views

Category:

Technology


2 download

TRANSCRIPT

•• http://goo.gl/WXRg0l

•• http://goo.gl/XRf4kl

2

ソースコード参照

••

1.

2.

3.

4.

5.

••

•••

••

var answer = 0;

for (int number = 1; number <= 10; number++)

answer += number;

var answer = Enumerable.Range(1, 10).Sum();

••

••

void Clock(Action onTick)

{

onTick();

Observable.Interval(TimeSpan.FromSeconds(1))

.ObserveOn(SynchronizationContext.Current)

.Subscribe(_ => onTick());

}

ソースコード参照

var drag = this.MouseDownAsObservable()

.SelectMany(_ => this.MouseMoveAsObservable())

.TakeUntil(this.MouseUpAsObservable());

ソースコード参照

IEnumerable<int> sequence1 = new[] { 1, 1, 2, 3, 5, 8, 13, 21, 34 };

IEnumerable<int> sequence2 = sequence1.Where (x => x % 2 == 0);

IEnumerable<int> sequence3 = sequence2.Select (x => x * x );

foreach (int item in sequence3)

Console.WriteLine(item);

ソースコード参照

IEnuramerable<T>

Where<T>

Select<T, U>

IEnuramerable<U>

T型の要素のシーケンス

絞込み

各要素をT型からU型に変換

U型の要素のシーケンス

// 普通自動車運転免許を持ってる可能性のある人に電話をかける

public static void CallEligibleDrivers(IEnumerable<Person> people)

{

foreach (var person in people) {

if (person.Age >= 18)

Call(person);

}

}

ソースコード参照

IEnumerable<int> sequence1 = new[] { 1, 1, 2, 3, 5, 8, 13, 21, 34 };

IEnumerable<int> sequence2 = sequence1.Where (x => x % 2 == 0);

IEnumerable<int> sequence3 = sequence2.Select (x => x * x );

foreach (int item in sequence3)

Console.WriteLine(item);

IEnumerable<T>

Where<T>

Select<T, U>

IEnumerable<U>

T型の要素のシーケンス

絞込み

各要素をT型からU型に変換

U型の要素のシーケンス

IEnumerable<T>

Where<T>

Select<T, U>

IEnumerable<U>

IEnumerator が要素にアクセス

IEnumerator が要素にアクセス

要素を取り出そうとする度

IEnumerator が要素にアクセス

var data = new[] { -1, 6, 7, 3, -2, 0, 5, 2, 7 };

var result = data.Where(number => number > 0)

.Select(number => string.Format("{0} mm", number / 1000.0));

foreach (var text in result)

Console.WriteLine(text);

ソースコード参照

実際に sequence3 から値が取り出されるまで、sequence1 から値は取り出されず、Where や Select に渡した

デリゲートも実行されない

IEnumerable<T>

Where<T>

Select<T, U>

IEnumerable<U>

式木を調べて(SQL などを動的に生成し)

要素を取り出す

要素を取り出そうとする式木

Debug.WriteLine("■ LINQ の実際の処理の流れ(LINQ to Entities) ■");

var data = new EmployeeModel();

data.Database.Log = message => Console.WriteLine(message);

var sequence1 = data.Employees;

var sequence2 = sequence1.Where(employee => employee.Name.Contains("川"));

var sequence3 = sequence2.Select(

employee => new { 番号 = employee.Number, 名前 = employee.Name });

Console.WriteLine("■ 出力開始 ■");

foreach (var employee in sequence3)

Console.WriteLine("{0}: {1}", employee.番号, employee.名前);

Console.WriteLine("■ 出力終了 ■");

ソースコード参照

実際に sequence3 から値が取り出されるときに式木から SQL を生成して発行

•• http://msdn.microsoft.com/ja-jp/library/system.linq.iqueryable(v=vs.110).aspx

public interface IQueryable : IEnumerable

{

Type ElementType { get; }

Expression Expression { get; }

IQueryProvider Provider { get; }

}

public interface IQueryable<T> : IEnumerable<T>, IQueryable

{}

•class Foo : IQueryable

{

public Type ElementType

{ get { throw new NotImplementedException(); } }

public Expression Expression

{ get { throw new NotImplementedException(); } }

public IQueryProvider Provider

{ get { throw new NotImplementedException(); } }

public IEnumerator GetEnumerator()

{ throw new NotImplementedException(); }

}

ソースコード参照

•••

••

var data = new EmployeeModel();

data.Database.Log = message => Debug.Write(message);

var sequence1 = data.Employees;

var sequence2 = sequence1.Where (employee => employee.Name.Contains("川"));

var sequence3 = sequence2.Select (

employee => new { 番号 = employee.Number, 名前 = employee.Name });

Debug.WriteLine("■ ラムダ式サンプル: 出力開始 ■");

foreach (var employee in sequence3)

Console.WriteLine("{0}: {1}", employee.番号, employee.名前);

Debug.WriteLine("■ ラムダ式サンプル: 出力終了 ■");

ソースコード参照

SELECT

[Extent1].[Number] AS [Number],

[Extent1].[Name] AS [Name]

FROM [dbo].[Employee] AS [Extent1]

WHERE [Extent1].[Name] LIKE N'%川%'

SELECT

[Extent1].[Number] AS [Number],

[Extent1].[Name] AS [Name],

[Extent1].[DepartmentID] AS [DepartmentID],

[Extent1].[EmailAddress] AS [EmailAddress]

FROM [dbo].[Employee] AS [Extent1]

public static class Queryable

{

public static IQueryable<T> Where<T>(this IQueryable<T> source,Expression<Func<T, bool>> predicate);

}

public static class Enumerable

{

public static IEnumerable<T> Where<T>(this IEnumerable<T> source,Func<T, int, bool> predicate);

}

••

class Program

{

static void Main()

{

Func<int, int, int> sequence1 = (x, y) => x + y;

Func<int, int, int> sequence2 = (x, y) => { return x + y; };

Expression<Func<int, int, int>> expression1 = (x, y) => x + y;

//Expression<Func<int, int, int>> expression2 = (x, y) => { return x + y; };

}

}

ブロックが含まれるラムダ式は式として扱えない(IQueryable<T> には使えない)

ソースコード参照

var sequence4 = from employee in data.Employee

where employee.Name.Contains("田")

select new { 番号 = employee.Id,名前 = employee.Name };

••

••

•ソースコード

参照

// メソッド構文

var fizzBuzzs = Enumerable.Range(1, 50).Select(FizzBuzz);

// クエリー構文

var fizzBuzzs = from number in Enumerable.Range(1, 50)

select FizzBuzz(number);

•ソースコード

参照

// メソッド構文

var numbers = Enumerable.Range(1, 9)

.SelectMany(x => Enumerable.Range(1, 9),

(x, y) => string.Format("{0}x{1}={2}", x, y, x * y));

// クエリー構文

var numbers = from x in Enumerable.Range(1, 9)

from y in Enumerable.Range(1, 9)

select string.Format("{0}x{1}={2}", x, y, x * y);

•ソースコード

参照

// メソッド構文

var numbers = new[] { 2, 6, 1, 3, -7, 1, -6, 0, -3 }

.Where(number => number % 2 == 0);

// クエリー構文

var numbers = from number in new[] { 2, 6, 1, 3, -7, 1, -6, 0, -3 }

where number % 2 == 0

select number;

•ソースコード

参照

// メソッド構文

var orderedPeople = people.OrderByDescending(person => person.Age)

.ThenBy(person => person.Name);

// クエリー構文

var orderedPeople = from person in people

orderby person.Age descending, person.Name

select person;

•ソースコード

参照

// メソッド構文

var collection = Enumerable.Range(1, 10)

.Select(x => x * x)

.Where(x => x > 50);

// クエリー構文

var collection = from n in Enumerable.Range(1, 10)

select n * n into m

where m > 50

select m;

•ソースコード

参照

// メソッド構文

var collection = books.GroupBy(book => book.Genre);

// クエリー構文

var collection = from book in books

group book by book.Genre;

•• https://msdn.microsoft.com/ja-jp/library/bb546133.aspx

•ソースコード

参照

// メソッド構文

var collection = bookGenres.Join(books,

bookGenre => bookGenre.Genre,

book => book.Genre,

(bookGenre, book) =>

new { Genre = bookGenre.Name, Title = book.Title });

// クエリー構文

var collection = from bookGenre in bookGenres

join book in books on bookGenre.Genre equals book.Genre

select new { Genre = bookGenre.Name, Title = book.Title };

•ソースコード

参照

var numbers1 = new int[] { 10, 20, 30, 40, 50 };

var numbers2 = new int[] { 1, 2, 3 };

// メソッド構文

var collection = numbers1.Zip(

numbers2,

(number1, number2) => number1 + number2

);

•ソースコード

参照

// メソッド構文

var numbers = Enumerable.Range(1, 5);

var result = numbers.Aggregate(

1, (sum, number) => sum * number);

•ソースコード

参照

var min = numbers.Min();

var max = numbers.Max();

var sum = numbers.Sum();

var average = numbers.Average();

•ソースコード

参照

•static string 数字だけの文字列に変換(string text)

{

var stringBuilder = new StringBuilder();

foreach (var character in text) {

if (Char.IsDigit(character))

stringBuilder.Append(character);

}

return stringBuilder.ToString();

}

static void Main()

{

var text = "3458y139h+(vq9eras^(&da23-8941asdf; asdf';";

Console.WriteLine(数字だけの文字列に変換(text));

}

ソースコード参照

• 問題 : Question.cs• 答えの例: Answer.cs

•ソースコード

参照

• 問題 : Question.cs• 答えの例: Answer.cs