for
やforeach
でループの回数を知りたい場合、こんな感じでループの外にカウンタ変数を定義してループ内でインクリメントしてました。
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以降)で使用できます。
古い環境ではLinq
のSelect
を使う方法が無難でしょうか。
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