LoginSignup
11
7

【C#】foreachでカウンタ変数を使わずにindexが知りたい

Last updated at Posted at 2024-05-23

forforeachでループの回数を知りたい場合、こんな感じでループの外にカウンタ変数を定義してループ内でインクリメントしてました。

List<string> list = new List<string> { "a", "i", "u", "e", "o" };
int index = 0;

foreach (var value in list)
{
    Console.WriteLine("value = {0}, index = {1}", value, index);
    index++;
}

このindexを定義せずにループの回数を調べる方法です。

LINQのSelectメソッドを使用する

DataTableで使う時はdataTable.AsEnumerable()とするとSelectが使えます。

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        List<string> list = new List<string> { "a", "i", "u", "e", "o" };

        // 値とインデックスのペアを作成
        var indexedList = list.Select((value, index) => new { value, index });

        foreach (var item in indexedList)
        {
            Console.WriteLine($"value = {item.value}, index = {item.index}");
        }
    }
}

実行結果

value = a, index = 0
value = i, index = 1
value = u, index = 2
value = e, index = 3
value = o, index = 4

LINQのZipメソッドを使用する

Zipメソッドは2つの要素を結合して、それらの要素をペアにした新しい要素を作成してくれます。
1つ目のシーケンスとしてリストを、2つ目のシーケンスとしてインデックスの範囲を使用してます。

Enumerable.Range(0, list.Count)で、0からリストの要素数までの連続した数字を作成します。

Selectの方がわかりやすいと思う。

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        List<string> list = new List<string> { "a", "i", "u", "e", "o" };

        // リストとインデックスの範囲をZipメソッドで結合
        var zipped = list.Zip(Enumerable.Range(0, list.Count), (value, index) => new { value, index });

        foreach (var item in zipped)
        {
            Console.WriteLine($"value = {item.value}, index = {item.index}");
        }
    }
}
value = a, index = 0
value = i, index = 1
value = u, index = 2
value = e, index = 3
value = o, index = 4

タプルを使用する

タプルはC#7.0以降(.NET Framework 4.7以降、または.NET Core以降)で使用できます。
古い環境ではLinqSelectを使う方法が無難でしょうか。

Selectではこうだったところが、
list.Select((value, index) => new { value, index });
タプルを使うとこうなります。
list.Select((value, index) => (value, index));
少しスッキリして良いのではないでしょうか!

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        List<string> list = new List<string> { "a", "i", "u", "e", "o" };

        // 値とインデックスのタプルを作成
        var indexedList = list.Select((value, index) => (value, index));

        foreach (var item in indexedList)
        {
            Console.WriteLine($"value = {item.value}, index = {item.index}");
        }
    }
}

コメントで教えてもらったんですけど、タプルの場合はこんな感じでもっとシンプルに書けました😊

foreach ((string value, int index) in list.Select((v, i) => (v, i)))
{
    Console.WriteLine($"value = {value}, index = {index}");
}

実行結果

value = a, index = 0
value = i, index = 1
value = u, index = 2
value = e, index = 3
value = o, index = 4
11
7
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
7