ぷろみん

プログラミング的な内容を扱ってます

forに名前を付けてあげましょう

概要

何故forを使うべきでないかを解説します。

比較

とりあえず、forを使った例と使わなかった例を見てみましょう。

// for
int items_count = 0;
for(auto item: v){
    if(item == 3){
        ++items_count;
    }
}

// non for
int items_count = std::count(v.begin(), v.end(), 3);

ここでポイントなのはforを使わない方が簡潔に書ける所でしょうか?
いいえ、重要なのは数を数えている事が明示されている事です。

forは便利です。何でもできます。
ですが、それ故に何をしているのか判断する必要があります。

それを踏まえた上で次の例を見てみましょう。

// for
int items_count = 0;
for(auto item: v){
    if(item % 3 == 0){
        ++items_count;
    }
}

// non for
int items_count = std::count_if(v.begin(), v.end(), [](auto item){
    return item % 3 == 0;
});

見た目がほとんど同じになってきました。
むしろforを使わない方がイテレータの取得やラムダが出てきて汚い印象すら受けます。

しかし、変わらずカウントしている事は明白です。
それは何故か、見て分かる通りcount関数を使っているから以上の差はありません。

関数で考えてみてください。

auto For1(){ ... }
auto For2(){ ... }
auto For3(){ ... }

auto Count(){ ... }
auto Find(){ ... }
auto AllOf(){ ... }

どっちが分かりやすいかは明白ですよね。
algorithmライブラリの提供するものは名前の付いたfor文です。
自分のforがalgorithmの関数で書けないのなら作りましょう。
名前の付いていないfor文は分かりにくいと認識しましょう。

そして、そのforにふさわしい名前を付けてあげてください。

LINQファースト

C#ではLINQファーストという考え方があるそうです。
LINQを使う事ができるか考え、LINQが使えないと判断した場合のみforを使うという考え方です。
これもforに名前を付けるという考え方と同じだと思います。
forではなく、LINQを使っている事によりLINQに向いている処理をしていると判断できます。