[C#]foreach文でループカウンタを取得する方法

C#でforeachを使用してループを行うと、シンプルな表記で集合内のデータを処理する事ができるので便利ですが、何番目の値を処理しているかのループカウンタが無いのが不便です。

このような場合は、以下のようにSelect()メソッドを使用すると処理中データのindexを取得できます。

static void Main(string[] args) {
    string nameArray = new string[] { "alice", "bob", "charlie", "dave" };
 
    foreach ( var nameObj in nameArray.Select( (value, index) => new { value, index } ) ) {
 
        // nameObjのメンバであるindexよりループカウンタを取得可能
        Console.WriteLine( "{0}人目: 名前{0}", nameObj.index, nameObj.value );
    }
}



ここで出てくるSelect()メソッドですが、これはEnumerableクラスのメンバなので、
例で使用している配列以外にListやDictionaryにも応用可能です。

Select()には、ラムダ式を引数として渡してあげます。
ラムダ式では2つのパラメータをもらっていますが、これはmsdnのオンラインマニュアルで確認すると、以下のように1つ目が処理中の値で2つ目が0から始まるカウンタである事が分かります。

selector の最初の引数は、処理する要素を表します。 selector の 2 つ目の
引数は、ソース シーケンス内のその要素の 0 から始まるインデックスを表します。 
 
これは、たとえば、要素が既知の順序である場合に、特定のインデックスにある要素
に対してなんらかの処理を行うときに役立つことがあります。 
 
また、1 つ以上の要素のインデックスを取得する場合にも役立つことがあります。


http://msdn.microsoft.com/ja-jp/library/bb534869.aspx より


シンプルかつとても便利な表記法ですが、注意点としては、Select()は、LINQの導入とともに追加された機能なので.NetFrameworkの3.5以上である必要があります。また、1要素処理するたびにnewしているので、集合内のデータ件数が膨大な場合は(シンプルなforeachに比べると)処理に時間が掛かる危険があります。

C#プログラムの効率的な書き方

関連記事

コメントを残す

メールアドレスが公開されることはありません。