LoginSignup
8
2

More than 5 years have passed since last update.

JS の「for...of」や C# の「foreach...in」でインデックスを使う方法を考える

Posted at

for(;;)文はインデックスの指定や配列の長さが必要だったり、
終了条件を間違えたりするのでなるべく使いたくないです。

for(;;)を使わずにインデックスにアクセスするとなると、JS の場合、Array.mapArray.forEachなど配列の反復処理、C# の場合、LINQ が思いつきます。
ただ、(個人的にですが)匿名メソッドのブロック本体に長々書くのもなんかしっくりきません。

// arr <- 配列
arr.forEach((v, i) => {
  /*
   * 長くていろいろやる 
   * 
   * 
   */
})

(C#の場合List<T>.ForEachが非推奨の理由もあるようです。)

そこで JS のfor...ofや C# のforeach...inでインデックスにアクセスする方法がないかなと考えてみました。。

JavaScript の for...of でインデックスを使う

const chars = ['J', 'a', 'v', 'a', 'S', 'c', 'r', 'i', 'p', 't']

for (const { c, i } of chars.map((c, i) => ({c, i}))) {
  /*
   * 長くていろいろやる 
   * 
   * 
   */
  console.log(`文字:${c} index:${i}`)
}
結果
 文字:J index:0
 文字:a index:1
 文字:v index:2
 文字:a index:3
 文字:S index:4
 文字:c index:5
 文字:r index:6
 文字:i index:7
 文字:p index:8
 文字:t index:9

mapでインデックスと要素を持ったオブジェクトの配列を作り、それを分割代入で受け取ります。

ラムダ式の戻り値のオブジェクト{}を囲む丸カッコ()は必須です。
メソッド本体が1ステートメントのラムダ式でオブジェクトを返す場合、
(){}を囲まないと{}がラムダ式の本体のブロックとみなされます。

欠点としてはmapが即時実行のため、mapfor...ofの間で中間配列ができてしまいます。
極端に長い配列を処理する場合などメモリを圧迫する場合はやめたほうがよさそうです。

C# の foreach...in でインデックスを使う方法

char[] chars = { 'c', 's', 'h', 'a', 'r', 'p' };
foreach (var (c, i) in chars.Select((c, i) => (c, i))) {
    /*
     *
     * なんか長い処理
     *
     */
    Console.WriteLine($"文字{c} index:{i}");
}
結果
 文字c index:0
 文字s index:1
 文字h index:2
 文字a index:3
 文字r index:4
 文字p index:5

LINQ のSelectで要素とインデックスのタプルのシーケンスを作り、分割代入で受け取ってます。
LINQ は遅延実行なので、Selectforeachで中間配列が作られることはありません。

Selectで匿名型new { c, i }のシーケンスを作ることもできますが、 JS と違い分割代入できません。foreachブロック中でx.cのようにアクセスしなければならず、普通のfor(;;)のほうがよさそうです。

x.のプリフィックスがイケてない...
char[] chars = { 'c', 's', 'h', 'a', 'r', 'p' };
foreach (var x in chars.Select((c, i) => new { c, i })) {
    /*
     *
     * なんか長い処理
     *
     */
    Console.WriteLine($"文字{x.c} index:{x.i}");
}
8
2
2

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
8
2