Quantcast
Channel: かずきのBlog@hatena
Viewing all articles
Browse latest Browse all 1387

ループの最初だけ特別な処理を行いたい(追記あり)

$
0
0

データの配列やListがあったときに、ループを回して処理を行うことってよくありますよね。しかも、最初だけなにか特別なことをおこないたい。一般的な方法だと、ループのインデックスを見て処理するほうほうがあります。

var data = new[] { 0, 1, 2, 3, 4, 5, 6, 7 };

// ループインデックスfor (int i = 0; i < data.Length; i++)
{
    if (i == 0)
    {
        Console.WriteLine("最初にやる処理 {0}", i);
        continue;
    }

    Console.WriteLine("{0}", i);
}

まぁ特に問題はないですけど、なんとなくいつも書いててもやっとしてる処理です。あとは、foreachで回したいときとかはフラグを使ったりしますよね。

var data = new[] { 0, 1, 2, 3, 4, 5, 6, 7 };

// フラグbool isFirst = true;
foreach (var i in data)
{
    if (isFirst)
    {
        Console.WriteLine("最初にやる処理 {0}", i);
        isFirst = false;
        continue;
    }

    Console.WriteLine("{0}", i);
}

これらのやりかたは、別にいいんですけど何かデータのループ処理で最初の要素のためだけに分岐を入れるのはコードがちょっと複雑になりがちでいやだったんです。ということで、LINQ使ってこんな方法。

var data = new[] { 0, 1, 2, 3, 4, 5, 6, 7 };

// LINQif (data.Any())
{
    var first = data.First();
    Console.WriteLine("最初にやる処理 {0}", first);
    foreach (var i in data.Skip(1))
    {
        Console.WriteLine("{0}", i);
    }
}

Firstで最初の要素を取得して、最初の要素のための処理をおこなって、Skipで最初の要素をスキップして残りの要素にループを行うという方法です。Firstは、シーケンスが空だと例外が出るので、Anyをつかってコレクションが空じゃないときだけ処理するようにしています。今度から、こういう風に書こうかな。

追記:LINQの書き方のダメなところ

Any ->処理はIEnumerableの場合遅延評価で重たい処理が走る可能性 + そのあとのループで再度重たい処理が走るという可能性があるのでNGでした。Facebookで指摘してくれたのいえさん多謝です。ということでフラグかな…。

汎用的な部品については、のいえさんが以前書かれてたので、どうしても必要な場合はこれでいいかも。

neue cc - Razorで空テンプレートとセパレータテンプレート


Viewing all articles
Browse latest Browse all 1387

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>