配列の要素を一つずつ処理するときにindex
も欲しくなること、ありませんか?
従来であれば
var values = new int[] { 5, 4, 3, 2, 1, 0 };
このような配列に対して、
for (var i = 0; i < values.Length; i++)
{
var v = values[i];
// ほげほげ
}
のようにfor
文を使用するか、
foreach (var o in values.Select((v, i) => new { Value = v, Index = i }))
{
var v = o.Value;
var i = o.Index;
// ほげほげ
}
のように匿名クラスを使う方法がありました。
前者はちょっとめんどくさいですし、後者は匿名クラスを使うのでアロケーションが気になります。
C# 7.0から使える値タプル(ValueTuple)と分解(Deconstruction)を使用すれば以下のようになります。
foreach (var (value, index) in values.Select((v, i) => (v, i)))
{
// ほげほげ
}
まるで別言語のような書き方ですがとてもシンプルになりました
余分な変数を作ってしまわないのもいい感じです
注意点として、パフォーマンスを追い求めるなら最初のfor文を使用する方法が一番良いです。
これは配列の範囲チェックやそもそもSelect
を行った時点でクラスがアロケートされてしまうからです。
配列の場合は匿名クラスを使うよりかは幾分ましですし、もともと添字でアクセスできないようなIEnumerable
に対してはなかなかいい方法なんじゃないかと思います。