トップページに戻る
C#メモ
C#で作ったツール(コンソールアプリ)
C# LINQメモ
目次
001. Whereメソッド
using System.Linq;
class Program
{
static void Main()
{
int[] work = { 1, 2, 3, 4, 5, 6 };
var work2 = work.Where((x) => x > 3);
foreach (var a in work2) {
System.Console.WriteLine(a.ToString());
}
}
}
//出力結果
4
5
6
002. GroupByメソッドとCountメソッド
using System.Linq;
class Program
{
static void Main()
{
int[] tmp = { 1, 1, 2, 2, 3, 3, 3, 4, 5 };
var work = tmp.GroupBy(X => X).Select(X => new { X.Key, cnt = X.Count()});
foreach (var a in work) {
System.Console.WriteLine(a);
}
}
}
//出力結果
{ Key = 1, cnt = 2 }
{ Key = 2, cnt = 2 }
{ Key = 3, cnt = 3 }
{ Key = 4, cnt = 1 }
{ Key = 5, cnt = 1 }
003. Skipメソッド,Takeメソッド
using System.Linq;
class Program
{
static void Main()
{
int[] tmp1 = { 1, 1, 2, 2, 3, 4, 5 };
var work = tmp1.OrderBy(X => X)
.Skip(2)
.Take(3);
foreach (int a in work) {
System.Console.WriteLine(a);
}
}
}
//出力結果
2
2
3
004. Unionメソッド,Concatメソッド
using System.Linq;
class Program
{
static void Main()
{
int[] tmp1 = { 1, 1, 2, 2, 3, 4, 5 };
int[] tmp2 = { 8, 7 };
int[] tmp3 = { 6, 7 };
//ConcatがSQLのUnion all
//UnionがSQLのUnion
var work = tmp1.Concat(tmp2)
.Concat(tmp3);
foreach (var a in work) {
System.Console.WriteLine(a);
}
}
}
//出力結果
1
1
2
2
3
4
5
8
7
6
7
005. FizzBuzz
using System.Linq;
class Program
{
static void Main()
{
var work = Enumerable.Range(1, 100)
.Select(X =>
{
if (X % 3 == 0 && X % 5 == 0) return "FizzBuzz";
if (X % 3 == 0) return "Fizz";
if (X % 5 == 0) return "Buzz";
return X.ToString();
});
foreach (var a in work) {
System.Console.WriteLine(a);
}
}
}
//出力結果
1
2
Fizz
4
Buzz
以下略
006. Reverse,OrderBy,OrderByDescendingメソッド
using System.Linq;
class Program
{
static void Main()
{
int[] arr = { 2, 4, 8, 3, 5, 7 };
//arr = arr.Reverse().ToArray();
arr = arr.OrderBy(X => X).ToArray();
//arr = arr.OrderByDescending(X => X).ToArray();
foreach (int each in arr) {
System.Console.WriteLine(each);
}
}
}
007. 匿名classの配列
using System.Linq;
class Program
{
static void Main()
{
var arr = new[] {new{ID = 1,Val = 3},
new{ID = 1,Val = 4},
new{ID = 1,Val = 5},
new{ID = 2,Val = 6},
new{ID = 2,Val = 7},
new{ID = 2,Val = 8},};
var SQL = arr.GroupBy(X => X.ID)
.Select(X => new { X.Key, cnt = X.Count() });
foreach (var each in SQL) {
System.Console.WriteLine(each);
}
}
}
008. 組み合わせの列挙
using System;
using System.Linq;
class Program
{
static void Main()
{
string line = "1,2 5,6,7";
var with1 = line.Split(' ').Select(c => c.Split(',').AsEnumerable());
var query = with1.Aggregate((xs, ys) => xs.SelectMany(_ => ys, (x, y) => x + '-' + y));
foreach (var each in query) Console.WriteLine(each);
}
}
//出力結果
//1-5
//1-6
//1-7
//2-5
//2-6
//2-7
009. 複数項目をSum
using System.Linq;
class Program
{
static void Main()
{
var arr = new[] {new{Val1 = 1,Val2 = 3},
new{Val1 = 0,Val2 = 7},
new{Val1 = 4,Val2 = 5},
new{Val1 = 0,Val2 = 5},
new{Val1 = 5,Val2 = 2},
new{Val1 = 5,Val2 = 8},};
var query = arr.GroupBy(A => 1)
.Select(A => new
{
sumVal1 = A.Sum(B => B.Val1),
sumVal2 = A.Sum(B => B.Val2),
cnt = A.Count()
});
foreach (var each in query) {
System.Console.WriteLine(each);
}
}
}
//出力結果
//{ sumVal1 = 15, sumVal2 = 30, cnt = 6 }
010. Select拡張メソッドでRowNum擬似列もどき
MSDN --- Select(TSource, TResult) メソッド
using System.Linq;
class Program
{
static void Main()
{
var arr = new[] {new{Val1 = 1,Val2 = 3},
new{Val1 = 0,Val2 = 7},
new{Val1 = 4,Val2 = 5},
new{Val1 = 0,Val2 = 5},
new{Val1 = 5,Val2 = 2},
new{Val1 = 5,Val2 = 8},};
var query = arr.Select((X, rn) => new { X.Val1, X.Val2, rn });
foreach (var each in query) {
System.Console.WriteLine(each);
}
}
}
//出力結果
//{ Val1 = 1, Val2 = 3, rn = 0 }
//{ Val1 = 0, Val2 = 7, rn = 1 }
//{ Val1 = 4, Val2 = 5, rn = 2 }
//{ Val1 = 0, Val2 = 5, rn = 3 }
//{ Val1 = 5, Val2 = 2, rn = 4 }
//{ Val1 = 5, Val2 = 8, rn = 5 }
011. クエリ構文とメソッド構文の比較
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
struct Struct1Def
{
internal int ID;
internal string Name;
}
static List<Struct1Def> Struct1List = new List<Struct1Def>();
struct Struct2Def
{
internal int ID;
internal string Name;
}
static List<Struct2Def> Struct2List = new List<Struct2Def>();
static void Main()
{
try {
DataInit();
Console.WriteLine("InnerJoin");
Exec_InnerJoin();
Console.WriteLine("LeftJoin");
Exec_LeftJoin();
}
catch (Exception Ex) {
Console.WriteLine(Ex.StackTrace);
}
}
static void DataInit()
{
Struct1List.Add(new Struct1Def { ID = 1, Name = "111" });
Struct1List.Add(new Struct1Def { ID = 2, Name = "222" });
Struct1List.Add(new Struct1Def { ID = 6, Name = "333" });
Struct2List.Add(new Struct2Def { ID = 1, Name = "AAA" });
Struct2List.Add(new Struct2Def { ID = 2, Name = "BBB" });
Struct2List.Add(new Struct2Def { ID = 9, Name = "CCC" });
}
static void Exec_InnerJoin()
{
//クエリ構文
var QueryKoubun = from A in Struct1List
join B in Struct2List
on A.ID equals B.ID
select new { A.ID, A_Name = A.Name, B_Name = B.Name };
foreach (var EachLine in QueryKoubun) {
Console.WriteLine("ID = {0} , A_Name = {1} , B_Name = {2}",
EachLine.ID, EachLine.A_Name, EachLine.B_Name);
}
//メソッド構文
var MethodKoubun = Struct1List.Join(Struct2List, A => A.ID, B => B.ID,
(A, B) => new { A.ID, A_Name = A.Name, B_Name = B.Name });
if (MethodKoubun.SequenceEqual(QueryKoubun) == false)
throw new Exception("クエリ構文とメソッド構文の結果が違います");
}
static void Exec_LeftJoin()
{
//クエリ構文
var QueryKoubun = from A in Struct1List
join B in Struct2List
on A.ID equals B.ID into tmp1
from tmp2 in tmp1.DefaultIfEmpty(
new Struct2Def { ID = A.ID, Name = "Null" })
select new
{
A.ID,
A_Name = A.Name,
B_Name = tmp2.Name
};
foreach (var EachLine in QueryKoubun) {
Console.WriteLine("ID = {0} , A_Name = {1} , B_Name = {2}",
EachLine.ID, EachLine.A_Name, EachLine.B_Name);
}
//メソッド構文
var MethodKoubun = Struct1List.GroupJoin(Struct2List, A => A.ID, B => B.ID,
(A, B) => new
{
A.ID,
A_Name = A.Name,
Tmp = B.DefaultIfEmpty(
new Struct2Def { ID = A.ID, Name = "Null" })
}).SelectMany(A => A.Tmp,
(A, B) => new
{
A.ID,
A.A_Name,
B_Name = B.Name
});
if (MethodKoubun.SequenceEqual(QueryKoubun) == false)
throw new Exception("クエリ構文とメソッド構文の結果が違います");
}
}
//出力結果
//InnerJoin
//ID = 1 , A_Name = 111 , B_Name = AAA
//ID = 2 , A_Name = 222 , B_Name = BBB
//LeftJoin
//ID = 1 , A_Name = 111 , B_Name = AAA
//ID = 2 , A_Name = 222 , B_Name = BBB
//ID = 6 , A_Name = 333 , B_Name = Null
012. TakeメソッドとSkipメソッド
TakeメソッドやSkipメソッドで、要素数より大きい数を指定しても、例外は発生しない。
using System;
using System.Linq;
class Program
{
static void Main()
{
Console.WriteLine("出力1");
foreach (int EachInt in Enumerable.Range(1, 5).Take(100))
Console.WriteLine(EachInt);
Console.WriteLine("出力2");
foreach (int EachInt in Enumerable.Range(1, 5).Skip(100))
Console.WriteLine(EachInt);
}
}
//出力結果
出力1
1
2
3
4
5
出力2
013. IEnumerable<IGrouping<TKey, TSource>>の使用
GroupByメソッドの結果は、IEnumerable<IGrouping<TKey, TSource>> という列挙になり、
その列挙に対して、WhereメソッドやMaxメソッドなどを使うことができます。
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
int[] wkArr = { 1, 1, 1, 1, 2, 3, 3, 3 };
//集約関数のネストもどき
int Query1 = wkArr.GroupBy(X => X).Max(A => A.Count());
Console.WriteLine("CountのMax={0}", Query1);
//Having句もどき
var Query2 = wkArr.GroupBy(X => X).Where(X => X.Count() > 1)
.Select(X => new { X.Key, cnt = X.Count() });
foreach (var EachTokumei in Query2) {
Console.WriteLine("{0}の件数={1}",
EachTokumei.Key, EachTokumei.cnt);
}
}
//出力結果
//CountのMax=4
//1の件数=4
//3の件数=3
}
014. Dictionary型同士でSequenceEqualで比較
キーでソートすれば、要素も含めて比較できる
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
var CntDictA = new Dictionary<int, int>();
var CntDictB = new Dictionary<int, int>();
CntDictA[1] = 11;
CntDictA[2] = 22;
CntDictA[3] = 33;
CntDictB[3] = 33;
CntDictB[1] = 11;
CntDictB[2] = 22;
if (CntDictA.OrderBy(pX => pX.Key).SequenceEqual(CntDictB.OrderBy(pX => pX.Key))) {
Console.WriteLine("Yes");
}
else {
Console.WriteLine("No");
}
}
}