Yuta.NET

C#のforeach文でインデックスを取得する小技


C#でfor文は絶滅危惧種です。foreach文でほぼ事足ります。while文は速度重視の際に使用されるかもですが...

ここではforeach文を使ってインデックスを取得する小技を紹介しますので上手く応用して可読性を上げよう!!

さてさて本題ですが、foreach文でインデックスを取得する方法は.NETのバージョンを上げることにより記述を簡略化することができます。

Linqが使える(.NET3.5以上)


foreach (var item in list.Select((value, index) => new { value, index }))

タプルが使える(.NET4.7以上)


foreach (var (value, index) in list.Select((v, i) => (v, i)))

また、拡張メソッドを用いることにより上記よりさらに簡略化し、下記のように汎用化することも出来ます。


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

namespace YutaCore.ConsoleApp1
{
    /// <summary>
    /// IEnumerable拡張メソッドクラス
    /// </summary>
    public static class IEnumerableExtensions
    {
        /// <summary>
        /// インデックス付コレクション(リスト)を返す
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="item"><c>IEnumerable<T></c></param>
        /// <returns>インデックス付コレクション</returns>
        public static IEnumerable<(T, int)> Select<T>(this IEnumerable<T> item)
        {
            return item.Select((v, i) => (v, i));
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            IEnumerable<string> list = new List<string> { "Apple", "Orange", "Meron", "Strawberry" };

            // Selectメソッドとタプルを使ってIndex付きデータを取得(注:この記述のタプルは.NET4.7以上で使用可)
            // 拡張メソッドを使いたくなければ
            // foreach (var (value, index) in list.Select((v, i) => (v, i)))
            foreach (var (value, index) in list.Select())
            {
                Console.WriteLine("{0}:{1}", index, value);
            }
            Console.ReadKey(true);
        }
    }
}