Download - C# LINQ ~深く知って、使いまくろう~
•• http://goo.gl/WXRg0l
•• http://goo.gl/XRf4kl
2
ソースコード参照
•
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);
ソースコード参照
•
// 普通自動車運転免許を持ってる可能性のある人に電話をかける
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>
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 に渡した
デリゲートも実行されない
•
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