「LINQ - 拡張メソッド一覧」の版間の差分

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動
編集の要約なし
 
(2人の利用者による、間の10版が非表示)
2行目: 2行目:
C#のLINQを種類ごとにまとめて、簡単なサンプルを記述する。<br>
C#のLINQを種類ごとにまとめて、簡単なサンプルを記述する。<br>
<br>
<br>
結果の表示に、独自の拡張メソッドToResult(this IEnumerable)を使用している。<br>
ここでは、結果の表示において、独自の拡張メソッドToResult(this IEnumerable)を使用している。<br>
このメソッドは、本文の最後に記載する。(サンプルコードのダウンロードはこちら)<br>
このメソッドを以下に記述する。<br>
<br><br>
<syntaxhighlight lang="c#">
 
// 結果表示用の拡張メソッド
== 要素の取得(単一) ==
public static String ToResult<TSource>(this IEnumerable<TSource> source)
該当の要素がない場合<br>
  {
* ~OrDefaultが付いていないメソッドは例外をスローする。<br>
    return "{" + string.Join(", ", source) + "}";
* ~OrDefaultが付いたメソッドは型の規定値を返す。<br>
  }
<center>
{| class="wikitable"
|-
! メソッド名 !! 機能
|-
| ElementAt<br>ElementAtOrDefault || 指定した位置(インデックス)にある要素を返す。
|-
| First<br>FirstOrDefault || 最初の要素を返す。
|-
| Last<br>LastOrDefault || 最後の要素を返す。
|-
| Single<br>SingleOrDefault || 唯一の要素を返す。該当する要素が複数ある場合、例外をスローする。
|}
</center>
<source lang="c#">
  var source = new[] { 3, 4, 5, 6, 7, 8, 9, 9 };
Console.WriteLine(source.ElementAt(2));
  // → 5
   
   
  Console.WriteLine(source.ElementAtOrDefault(10));
  public static String ToResult<TKey, TSource>(this IEnumerable<IGrouping<TKey, TSource>> source)
// → 0
  {
    return source.Select(group => string.Format("Key={0}, Source={1}", group.Key, group.ToResult())).ToResult();
Console.WriteLine(source.First());
  }
// → 3
  </syntaxhighlight>
Console.WriteLine(source.First(e => e > 5));
// → 6
Console.WriteLine(source.Last());
// → 9
Console.WriteLine(source.Last(e => e < 5));
// → 4
Console.WriteLine(source.Single());
// → System.InvalidOperationException: シーケンスに複数の要素が含まれている
Console.WriteLine(source.Single(e => e < 4 ));
// → 3
</source>
<br><br>
 
== 要素の取得(複数) ==
<center>
{| class="wikitable"
|-
! メソッド名 !! 機能
|-
| Where || 条件を満たす要素をすべて返す。
|-
| Distinct || 重複を除いたシーケンスを返す。
|-
| Skip || 先頭から指定された数の要素をスキップし、残りのシーケンスを返す。
|-
| SkipWhile || 先頭から指定された条件を満たさなくなるまで要素をスキップし、残りのシーケンスを返す。
|-
| Take || 先頭から指定された数の要素を返す。
|-
| TakeWhile || 先頭から指定された条件を満たす要素を返す。
|}
</center>
<source lang="c#">
var source = new[] { 3, 4, 5, 6, 7, 8, 9, 9 };
Console.WriteLine(source.Where(e => e > 5).ToResult());
// → {6, 7, 8, 9, 9}
Console.WriteLine(source.Distinct().ToResult());
// → {3, 4, 5, 6, 7, 8, 9}
Console.WriteLine(source.Skip(5).ToResult());
  // → {8, 9, 9}
Console.WriteLine(source.SkipWhile(e => e < 5).ToResult());
// → {5, 6, 7, 8, 9, 9}
Console.WriteLine(source.Take(5).ToResult());
// → {3, 4, 5, 6, 7}
Console.WriteLine(source.TakeWhile(e => e < 5).ToResult());
// → {3, 4}
</source>
<br><br>
 
== 集計 ==
<center>
{| class="wikitable"
|-
! メソッド名 !! 機能
|-
| Max || 最大値を返す。
|-
| Min || 最小値を返す。
|-
| Average || 平均値を返す。
|-
| Sum || 合計を返す。
|-
| Count || 要素数を返す。
|-
| Aggregate || アキュムレータ関数で処理した結果を返す。
|}
</center>
<source lang="c#">
var source = new[] { 3, 4, 5, 6, 7, 8, 9, 9 };
Console.WriteLine(source.Max());
// → 9
Console.WriteLine(source.Min());
// → 3
Console.WriteLine(source.Average());
// → 6.375
Console.WriteLine(source.Sum());
// → 51
Console.WriteLine(source.Count());
// → 8
Console.WriteLine(source.Aggregate((now, next) => now * next));
// → 1632960
// 参考:標本分散
double ave = source.Average();
Console.WriteLine(source.Sum(e => Math.Pow(e - ave, 2)) / source.Count());
  // → 4.484375
  </source>
<br><br>
<br><br>


== ソート ==
== ソート ==
<center>
<center>
{| class="wikitable"
{| class="wikitable" | style="background-color:#fefefe;"
|-
|-
! メソッド名 !! 機能
! style="background-color:#66CCFF;" | メソッド名  
! style="background-color:#66CCFF;" | 機能
|-
|-
| OrderBy || 昇順にソートしたシーケンスを返す。
| OrderBy || 昇順にソートしたシーケンスを返す。
159行目: 36行目:
|}
|}
</center>
</center>
  <source lang="c#">
  <syntaxhighlight lang="c#">
  var source = new[] {
  var source = new[] {
     new{Name = "C#", Age = 11},
     new{Name = "C#", Age = 11},
196行目: 73行目:
  //    { Name = Java, Age = 16},
  //    { Name = Java, Age = 16},
  //    { Name = C#, Age = 11 }}
  //    { Name = C#, Age = 11 }}
  </source>
  </syntaxhighlight>
<br><br>
<br><br>


== 射影 ==
<center>
<center>
{| class="wikitable"
{| class="wikitable" | style="background-color:#fefefe;"
|-
|-
! メソッド名 !! 機能
! style="background-color:#66CCFF;" | メソッド名  
! style="background-color:#66CCFF;" | 機能
|-
|-
| Select || 1つの要素を単一の要素に射影する。
| Select || 1つの要素を単一の要素に射影する。
211行目: 90行目:
|}
|}
</center>
</center>
  <source lang="c#">
  <syntaxhighlight lang="c#">
  var source = new[] {
  var source = new[] {
     new{Name = "C#", Age = 11},
     new{Name = "C#", Age = 11},
229行目: 108行目:
  //    Key=16, Source={{ Name = Java, Age = 16 }},
  //    Key=16, Source={{ Name = Java, Age = 16 }},
  //    Key=8, Source={{ Name = Groovy, Age = 8 }, { Name = Scala, Age = 8 }}}
  //    Key=8, Source={{ Name = Groovy, Age = 8 }, { Name = Scala, Age = 8 }}}
  </source>
  </syntaxhighlight>
<br><br>
 
== 結合 ==
<center>
{| class="wikitable" | style="background-color:#fefefe;"
|-
! style="background-color:#66CCFF;" | メソッド名
! style="background-color:#66CCFF;" | 機能
|-
| Join || 内部結合を行ったシーケンスを返す。
|-
| GroupJoin || 左外部結合を行って指定のキーでグループ化する。その "キーとグループ" のシーケンスを返す。
|-
| Concat || 2つのシーケンスを連結する。(Unionは同じ要素を一つにまとめるが、Concatは元の要素をすべて返す)
|-
| DefaultIfEmpty || シーケンスを返す。シーケンスが空なら、規定値もしくは任意の要素を返す。
|-
| Zip || 指定した関数で、2つのシーケンスを1つのシーケンスにマージする。
|}
</center>
<syntaxhighlight lang="c#">
var outer = new[] {
    new{Name = "C#", Age = 11},
    new{Name = "Java", Age = 16},
    new{Name = "Groovy", Age = 8},
    new{Name = "Scala", Age = 8},
};
var outer2 = new[] {
    new{Name = "Python", Age = 21},
    new{Name = "COBOL", Age = 52},
};
var inner = new[] {
    new{Name = "C#", DesignedBy = "Microsoft"},
    new{Name = "Java", DesignedBy = "Sun Microsystems"},
    new{Name = "Java", DesignedBy = "Oracle"},
};
Console.WriteLine(outer.Join(inner, o => o.Name, i => i.Name, (o, i) => new { o.Name, o.Age, i.DesignedBy}).ToResult());
// → {{ Name = C#, Age = 11, DesignedBy = Microsoft },
//    { Name = Java, Age = 16, DesignedBy = Sun Microsystems },
//    { Name = Java, Age = 16, DesignedBy = Oracle }}
Console.WriteLine(outer.GroupJoin(inner, o => o.Name, i => i.Name, (o, i) =>
                                  new { o.Name, o.Age, DesigndBy = i.Select(e => e.DesignedBy).ToResult() }).ToResult());
// → {{ Name = C#, Age = 11, DesigndBy = {Microsoft} },
//    { Name = Java, Age = 16, DesigndBy = {Sun Microsystems, Oracle} },
//    { Name = Groovy, Age = 8, DesigndBy = {} },
//    { Name = Scala, Age = 8, DesigndBy = {} }}
Console.WriteLine(outer.Concat(outer2).ToResult());
// → {{ Name = C#, Age = 11 },
//    { Name = Java, Age = 16 },
//    { Name = Groovy, Age = 8 },
//    { Name = Scala, Age = 8 },
//    { Name = Python, Age = 21 },
//    { Name = COBOL, Age = 52 }}
Console.WriteLine(outer.DefaultIfEmpty().ToResult());
// → {{ Name = C#, Age = 11 },
//    { Name = Java, Age = 16 },
//    { Name = Groovy, Age = 8 },
//    { Name = Scala, Age = 8 }}
Console.WriteLine(outer.Zip(outer2, (o1, o2) => o1.Name + "&" + o2.Name).ToResult());
// → {C#&Python, Java&COBOL}
</syntaxhighlight>
<br><br>
 
== 変換 ==
<center>
{| class="wikitable" | style="background-color:#fefefe;"
|-
! style="background-color:#66CCFF;" | メソッド名
! style="background-color:#66CCFF;" | 機能
|-
| OfType || 各要素を指定した型に変換する。<br>キャストできない要素は除外する。
|-
| Cast || 各要素を指定した型に変換する。<br>キャストできない要素が含まれていた場合、例外をスローする。
|-
| ToArray || 配列を作成する。
|-
| ToDictionary || 連想配列(ディクショナリ)を作成する。
|-
| ToList ||リストを作成する。
|-
| ToLookup || キーコレクション*1を生成する。<br>IEnumerableと同じ名前のメソッドがクラス内に定義されている場合に使用する。<br>そのままだと、クラス内のメソッドが優先的に選択されて、<br>IEnumerableの拡張メソッドが呼びだせないためである。
|-
| AsEnumerable || IEnumerableを返す。<br>1対多のディクショナリである。<br>例えば、〜.ToLookup()["hoge"]と実行すると、hogeに紐付く要素の集合(IEnumerable)が返る。
|}
</center>
<br>
<syntaxhighlight lang="c#">
ArrayList mixed = new ArrayList { "C#", "Java", 3.141592653, "Groovy", "Scala" };
Console.WriteLine(mixed.OfType<string>().ToResult());
// → {C#, Java, Groovy, Scala}
Console.WriteLine(mixed.Cast<string>().ToResult());
// → System.InvalidCastException:
//    型 'System.Double' のオブジェクトを型 'System.String' にキャストできません。
</syntaxhighlight>
<br><br>
<br><br>


__FORCETOC__
__FORCETOC__
[[カテゴリ:C_Sharp]]
[[カテゴリ:C_Sharp]]

2024年9月27日 (金) 12:19時点における最新版

概要

C#のLINQを種類ごとにまとめて、簡単なサンプルを記述する。

ここでは、結果の表示において、独自の拡張メソッドToResult(this IEnumerable)を使用している。
このメソッドを以下に記述する。

 // 結果表示用の拡張メソッド
 public static String ToResult<TSource>(this IEnumerable<TSource> source)
 {
    return "{" + string.Join(", ", source) + "}";
 }
 
 public static String ToResult<TKey, TSource>(this IEnumerable<IGrouping<TKey, TSource>> source)
 {
    return source.Select(group => string.Format("Key={0}, Source={1}", group.Key, group.ToResult())).ToResult();
 }



ソート

メソッド名 機能
OrderBy 昇順にソートしたシーケンスを返す。
OrderByDescending 降順にソートしたシーケンスを返す。
ThenBy ソートしたシーケンスに対し、キーが等しい要素同士を昇順にソートしたシーケンスを返す。
ThenByDescending ソートしたシーケンスに対し、キーが等しい要素同士を降順にソートしたシーケンスを返す。
Reverse 逆順にソートしたシーケンスを返す。
 var source = new[] {
    new{Name = "C#", Age = 11},
    new{Name = "Java", Age = 16},
    new{Name = "Groovy", Age = 8},
    new{Name = "Scala", Age = 8},
 };
 
 Console.WriteLine(source.OrderBy(e => e.Age).ToResult());
 // → {{ Name = Groovy, Age = 8 },
 //     { Name = Scala, Age = 8 }, 
 //     { Name = C#, Age = 11 },
 //     { Name = Java, Age = 16 }}
 
 Console.WriteLine(source.OrderByDescending(e => e.Age).ToResult());
 // → {{ Name = Java, Age = 16 },
 //     { Name = C#, Age = 11 },
 //     { Name = Groovy, Age = 8 },
 //     { Name = Scala, Age = 8 }}
 
 Console.WriteLine(source.OrderBy(e => e.Age).ThenBy(e => e.Name.Length).ToResult());
 // → {{ Name = Scala, Age = 8 },
 //     { Name = Groovy, Age = 8 },
 //     { Name = C#, Age = 11 },
 //     { Name = Java, Age = 16 }}
 
 Console.WriteLine(source.OrderBy(e => e.Age).ThenByDescending(e => e.Name.Length).ToResult());
 // → {{ Name = Groovy, Age = 8 },
 //     { Name = Scala, Age = 8 },
 //     { Name = C#, Age = 11 },
 //     { Name = Java, Age = 16 }}
 
 Console.WriteLine(source.Reverse().ToResult());
 // → {{ Name = Scala, Age = 8 },
 //     { Name = Groovy, Age = 8 },
 //     { Name = Java, Age = 16},
 //     { Name = C#, Age = 11 }}



射影

メソッド名 機能
Select 1つの要素を単一の要素に射影する。
SelectMany 1つの要素から複数の要素に射影する。その結果を1つのシーケンスとして返す。
GroupBy 指定のキーで要素をグループ化する。その"キーとグループ" のシーケンスを返す。
 var source = new[] {
    new{Name = "C#", Age = 11},
    new{Name = "Java", Age = 16},
    new{Name = "Groovy", Age = 8},
    new{Name = "Scala", Age = 8},
 };
 
 Console.WriteLine(source.Select(e => e.Name).ToResult());
 // → {C#, Java, Groovy, Scala}
 
 Console.WriteLine(source.SelectMany(e => e.Name.ToCharArray()).ToResult());
 // → {C, #, J, a, v, a, G, r, o, o, v, y, S, c, a, l, a}
 
 Console.WriteLine(source.GroupBy(e => e.Age).ToResult());
 // → {Key=11, Source={{ Name = C#, Age = 11 }},
 //     Key=16, Source={{ Name = Java, Age = 16 }},
 //     Key=8, Source={{ Name = Groovy, Age = 8 }, { Name = Scala, Age = 8 }}}



結合

メソッド名 機能
Join 内部結合を行ったシーケンスを返す。
GroupJoin 左外部結合を行って指定のキーでグループ化する。その "キーとグループ" のシーケンスを返す。
Concat 2つのシーケンスを連結する。(Unionは同じ要素を一つにまとめるが、Concatは元の要素をすべて返す)
DefaultIfEmpty シーケンスを返す。シーケンスが空なら、規定値もしくは任意の要素を返す。
Zip 指定した関数で、2つのシーケンスを1つのシーケンスにマージする。
 var outer = new[] {
    new{Name = "C#", Age = 11},
    new{Name = "Java", Age = 16},
    new{Name = "Groovy", Age = 8},
    new{Name = "Scala", Age = 8},
 };
 var outer2 = new[] {
    new{Name = "Python", Age = 21},
    new{Name = "COBOL", Age = 52},
 };
 var inner = new[] {
    new{Name = "C#", DesignedBy = "Microsoft"},
    new{Name = "Java", DesignedBy = "Sun Microsystems"},
    new{Name = "Java", DesignedBy = "Oracle"},
 };
 
 Console.WriteLine(outer.Join(inner, o => o.Name, i => i.Name, (o, i) => new { o.Name, o.Age, i.DesignedBy}).ToResult());
 // → {{ Name = C#, Age = 11, DesignedBy = Microsoft },
 //     { Name = Java, Age = 16, DesignedBy = Sun Microsystems },
 //     { Name = Java, Age = 16, DesignedBy = Oracle }}
 
 Console.WriteLine(outer.GroupJoin(inner, o => o.Name, i => i.Name, (o, i) =>
                                   new { o.Name, o.Age, DesigndBy = i.Select(e => e.DesignedBy).ToResult() }).ToResult());
 // → {{ Name = C#, Age = 11, DesigndBy = {Microsoft} },
 //     { Name = Java, Age = 16, DesigndBy = {Sun Microsystems, Oracle} },
 //     { Name = Groovy, Age = 8, DesigndBy = {} },
 //     { Name = Scala, Age = 8, DesigndBy = {} }}
 
 Console.WriteLine(outer.Concat(outer2).ToResult());
 // → {{ Name = C#, Age = 11 },
 //     { Name = Java, Age = 16 },
 //     { Name = Groovy, Age = 8 },
 //     { Name = Scala, Age = 8 },
 //     { Name = Python, Age = 21 },
 //     { Name = COBOL, Age = 52 }}
 
 Console.WriteLine(outer.DefaultIfEmpty().ToResult());
 // → {{ Name = C#, Age = 11 },
 //     { Name = Java, Age = 16 },
 //     { Name = Groovy, Age = 8 },
 //     { Name = Scala, Age = 8 }}
 
 Console.WriteLine(outer.Zip(outer2, (o1, o2) => o1.Name + "&" + o2.Name).ToResult());
 // → {C#&Python, Java&COBOL}



変換

メソッド名 機能
OfType 各要素を指定した型に変換する。
キャストできない要素は除外する。
Cast 各要素を指定した型に変換する。
キャストできない要素が含まれていた場合、例外をスローする。
ToArray 配列を作成する。
ToDictionary 連想配列(ディクショナリ)を作成する。
ToList リストを作成する。
ToLookup キーコレクション*1を生成する。
IEnumerableと同じ名前のメソッドがクラス内に定義されている場合に使用する。
そのままだと、クラス内のメソッドが優先的に選択されて、
IEnumerableの拡張メソッドが呼びだせないためである。
AsEnumerable IEnumerableを返す。
1対多のディクショナリである。
例えば、〜.ToLookup()["hoge"]と実行すると、hogeに紐付く要素の集合(IEnumerable)が返る。


 ArrayList mixed = new ArrayList { "C#", "Java", 3.141592653, "Groovy", "Scala" };
 
 Console.WriteLine(mixed.OfType<string>().ToResult());
 // → {C#, Java, Groovy, Scala}
 
 Console.WriteLine(mixed.Cast<string>().ToResult());
 // → System.InvalidCastException: 
 //    型 'System.Double' のオブジェクトを型 'System.String' にキャストできません。