Foreachループがあるとします。
ループの最初のオブジェクトで何かをする必要がありますが、他のオブジェクトでは処理する必要はありません。
現在ループ内にあるアイテムが最初のオブジェクトであるかどうかを確認するにはどうすればよいですか。
それにはいくつかの方法があります。
私はLinqの方法が好きですが、Skip(1)がなくても、この方法でリストの最後のアイテムにも使用でき、コードはきれいなままです:)
foreach(var item in items)
{
if (items.First()==item)
item.firstStuff();
else if (items.Last() == item)
item.lastStuff();
item.otherStuff();
}
このようなもの:
bool first = true;
foreach(var item in items)
{
if (first)
{
item.firstStuff();
first = false;
}
item.otherStuff();
}
これが高性能ソリューションです。
using (var erator = enumerable.GetEnumerator())
{
if (erator.MoveNext())
{
DoActionOnFirst(erator.Current);
while (erator.MoveNext())
DoActionOnOther(erator.Current);
}
}
編集:そして、ここにLINQがあります:
if (enumerable.Any())
{
DoActionOnFirst(enumerable.First());
foreach (var item in enumerable.Skip(1))
DoActionOnOther(item);
}
編集:アイテムのアクションにFunc<TItem, TResult>
に割り当て可能な署名がある場合、次のことができます。
enumerable.Select((item, index) => index == 0 ? GetResultFromFirstItem(item) : GetResultFromOtherItem(item));
これは、配列内の各オブジェクトとともにインデックスを取得するためのより一般的なソリューションです。初めての場合はテストしてください。
List<String> entries = new List<string>();
entries.Add("zero");
entries.Add("one");
entries.Add("two");
Dictionary<int, String> numberedEntries = new Dictionary<int, string>();
int i = 0;
entries.ForEach(x => numberedEntries.Add(i++, x));
foreach (KeyValuePair<int, String> pair in numberedEntries) {
Console.WriteLine(pair.Key + ": " + pair.Value);
}
このセットアップでは、KeyValuePairのキーはインデックスであり、値はそのインデックスのオブジェクト(この例では文字列)ですが、任意のオブジェクトをそこに配置できます。多少のオーバーヘッドが追加されますが、必要に応じてリストのインデックス内のオブジェクトを決定するために使用できます。
私の意見では、これが最も簡単な方法です
foreach (var item in list)
{
if((list.IndexOf(item) == 0)
{
// first
}
// others
}
bool first = true;
foreach(var foo in bar)
{
if (first)
{
// do something to your first item
first = false;
}
// do something else to the rest
}
何も考えられない
var processedFirst = false;
foreach(var x in items) {
if(!processedFirst) {
ProcessFirst(x);
processedFirst = true;
}
これを試して
bool IsFirst = true;
foreach(DataRow dr in dt.Rows)
{
if (IsFirst)
{
// do some thing
IsFirst = false;
}
}