foreachループ、ループの最後の反復を決定


233

foreachループがあり、最後の項目がから選択されたときにいくつかのロジックを実行する必要がありますList。例:

 foreach (Item result in Model.Results)
 {
      //if current result is the last item in Model.Results
      //then do something in the code
 }

forループとカウンターを使用せずに、どのループが最後かを知ることはできますか?


1
私が関連する質問に投稿した解決策については、ここで私の回答を見てください。
ブライアンギデオン2013

回答:


294

最後の要素で何かを行う必要がある場合(最後の要素で何か異なることを行うのではなく)、LINQを使用すると、次のようになります。

Item last = Model.Results.Last();
// do something with last

最後の要素を変更する必要がある場合は、次のようなものが必要です。

Item last = Model.Results.Last();
foreach (Item result in Model.Results)
{
    // do something with each item
    if (result.Equals(last))
    {
        // do something different with the last item
    }
    else
    {
        // do something different with every item but the last
    }
}

ただし、アイテムがによって返されたアイテムと同じであることを確認できるように、カスタムコンパレータを作成する必要がありますLast()

Lastコレクションを反復処理する必要がある場合があるため、このアプローチは注意して使用する必要があります。これは小さなコレクションでは問題にならないかもしれませんが、大きくなると、パフォーマンスに影響を与える可能性があります。リストに重複するアイテムが含まれている場合も失敗します。この場合、次のようなものがより適切です。

int totalCount = result.Count();
for (int count = 0; count < totalCount; count++)
{
    Item result = Model.Results[count];

    // do something with each item
    if ((count + 1) == totalCount)
    {
        // do something different with the last item
    }
    else
    {
        // do something different with every item but the last
    }
}

1
私が必要だったのは:ループが最後の項目を通過するとき:foreach(Model.Resultsの項目結果){if(result == Model.Results.Last()){<div> last </ div>; }同じことを意味しているようです。
事故

10
コードはコレクション全体で2回繰り返されます-コレクションが小さくなければ悪い。この答えを見てください。
Shimmy Weitzhandler 2013

54
コレクションに重複がある場合、これは実際には機能しません。たとえば、文字列のコレクションを使用していて、重複がある場合、その「最後のアイテムとは異なる」コードは、リスト内の最後のアイテムが出現するたびに実行されます。
muttley91 2013

7
この回答は古くなっていますが、この回答を見ている他の人にとっては、最後の要素を取得し、次を使用して要素をループする必要がないことを確認できます。Item last = Model.Results [Model.Results.Count-1]カウントリストのプロパティはループを必要としません。リストに重複がある場合は、forループで反復子変数を使用します。通常の古いforループは悪くありません。
Michael Harris、

私が使用して示唆var last = Model.Result[Model.Result.Count - 1];速く使用するよりもためにLast()
タン

184

古き良きforループはどうですか?

for (int i = 0; i < Model.Results.Count; i++) {

     if (i == Model.Results.Count - 1) {
           // this is the last item
     }
}

または、Linqとforeachを使用します。

foreach (Item result in Model.Results)   
{   
     if (Model.Results.IndexOf(result) == Model.Results.Count - 1) {
             // this is the last item
     }
}

14
forループがすでにそれを完全に実行できる場合、このような単純な問題を考えすぎている多くのpplがあります。:\
Andrew Hoffman

Linqソリューションが私のお気に入りです。共有してくれてありがとう
mecograph

これは、受け入れられた答えよりも適切な答えです。
Ratul

文字列(または値の型)のコレクションでLINQソリューションを使用したい人への注意:リストの最後の文字列もリストの前にある場合、==比較は失敗するため、通常は機能しません。重複する文字列がないことが保証されているリストを使用している場合にのみ機能します。
タワブワキル

残念ながら、Model.Resultsがである場合、この巧妙なソリューションは使用できませんIEnumerableCount()ループの前に呼び出すこともできますが、シーケンスの完全な反復が発生する可能性があります。
ルカクレモネシ

42

Last()特定のタイプで使用すると、コレクション全体がループします。
つまり、foreachを呼び出してを呼び出すとLast()2回ループすることになります大きなコレクションでは避けたいと思います。

次に、解決策はdo whileループを使用することです:

using var enumerator = collection.GetEnumerator();

var last = !enumerator.MoveNext();
T current;

while (!last)
{
  current = enumerator.Current;        

  //process item

  last = !enumerator.MoveNext();        
  if(last)
  {
    //additional processing for last item
  }
}

コレクション型のタイプがある場合を除きだから、この関数は、すべてのコレクション要素を通して反復します。IList<T>Last()

テスト

コレクションがランダムアクセスを提供する場合(たとえば、implements IList<T>)、次のようにアイテムをチェックすることもできます。

if(collection is IList<T> list)
  return collection[^1]; //replace with collection.Count -1 in pre-C#8 apps

1
列挙子にusingステートメントが必要ですか?これは、オブジェクトがオペレーティングシステムのリソースを処理する場合にのみ必要であり、マネージデータ構造では必要ないと考えました。
しゃがむ子猫

IEnumeratorはIDisposableを実装していないため、with withを使用した行ではコンパイル時エラーが発生します。ソリューションの+1。ほとんどの場合、列挙可能なコレクションアイテムは実行時に計算されるか、シーケンスがランダムアクセスをサポートしていないため、foreachの代わりに単にforを使用することはできません。
サレ


40

Chrisが示すように、Linqは機能します。Last()を使用して、列挙可能な最後の参照を取得します。その参照を使用していない限り、通常のコードを実行しますが、その参照を使用している場合は、追加の処理を実行します。その欠点は、常にO(N)の複雑さになることです。

代わりに、Count()(IEnumerableがICollectionの場合はO(1)です。これは、ほとんどの一般的な組み込みIEnumerableに当てはまります)を使用して、foreachをカウンターとハイブリッド化できます。

var i=0;
var count = Model.Results.Count();
foreach (Item result in Model.Results)
{
    if (++i == count) //this is the last item
}

22
foreach (var item in objList)
{
  if(objList.LastOrDefault().Equals(item))
  {

  }
}

こんにちは、これはこれまでのところ最高のアプローチです!シンプルで要領を得ています。プログラマー向けのアプローチ、1つ。なぜ私たちはこれを選択してさらに+1するのですか?
Hanny Setiawan 2017

1
最後のアイテムは、ブロックする前に1回だけ(メモをプロモート)見つける必要がありforeachます。このように:var lastItem = objList.LastOrDeafault();。次に、foreachループの内側から次のように確認できますf (item.Equals(lastItem)) { ... }。元の答えでは、objList.LastOrDefault()「foreach」の反復ごとにコレクションが反復されます(ポリノミアルの複雑さが関係しています)。
AlexMelw 2018年

悪い答え。nの代わりにn ^ 2の複雑さ。
Shimmy Weitzhandler

11

Shimmyが指摘したように、Last()の使用はパフォーマンスの問題になる可能性があります。たとえば、コレクションがLINQ式のライブ結果である場合などです。複数の反復を防ぐには、次のような「ForEach」拡張メソッドを使用できます。

var elements = new[] { "A", "B", "C" };
elements.ForEach((element, info) => {
    if (!info.IsLast) {
        Console.WriteLine(element);
    } else {
        Console.WriteLine("Last one: " + element);
    }
});

拡張メソッドは次のようになります(追加のボーナスとして、インデックスと、最初の要素を見ているかどうかもわかります)。

public static class EnumerableExtensions {
    public delegate void ElementAction<in T>(T element, ElementInfo info);

    public static void ForEach<T>(this IEnumerable<T> elements, ElementAction<T> action) {
        using (IEnumerator<T> enumerator = elements.GetEnumerator())
        {
            bool isFirst = true;
            bool hasNext = enumerator.MoveNext();
            int index = 0;
            while (hasNext)
            {
                T current = enumerator.Current;
                hasNext = enumerator.MoveNext();
                action(current, new ElementInfo(index, isFirst, !hasNext));
                isFirst = false;
                index++;
            }
        }
    }

    public struct ElementInfo {
        public ElementInfo(int index, bool isFirst, bool isLast)
            : this() {
            Index = index;
            IsFirst = isFirst;
            IsLast = isLast;
        }

        public int Index { get; private set; }
        public bool IsFirst { get; private set; }
        public bool IsLast { get; private set; }
    }
}

9

ダニエルウルフの答えをさらに向上させるIEnumerableと、次のような複数の反復とラムダを回避するために別のスタックに重ねることができます。

var elements = new[] { "A", "B", "C" };
foreach (var e in elements.Detailed())
{
    if (!e.IsLast) {
        Console.WriteLine(e.Value);
    } else {
        Console.WriteLine("Last one: " + e.Value);
    }
}

拡張メソッドの実装:

public static class EnumerableExtensions {
    public static IEnumerable<IterationElement<T>> Detailed<T>(this IEnumerable<T> source)
    {
        if (source == null)
            throw new ArgumentNullException(nameof(source));

        using (var enumerator = source.GetEnumerator())
        {
            bool isFirst = true;
            bool hasNext = enumerator.MoveNext();
            int index = 0;
            while (hasNext)
            {
                T current = enumerator.Current;
                hasNext = enumerator.MoveNext();
                yield return new IterationElement<T>(index, current, isFirst, !hasNext);
                isFirst = false;
                index++;
            }
        }
    }

    public struct IterationElement<T>
    {
        public int Index { get; }
        public bool IsFirst { get; }
        public bool IsLast { get; }
        public T Value { get; }

        public IterationElement(int index, T value, bool isFirst, bool isLast)
        {
            Index = index;
            IsFirst = isFirst;
            IsLast = isLast;
            Value = value;
        }
    }
}

1
もう1つの答えはソースを複数回反復しないため、修正する問題ではありません。あなたは確かにの使用を許可しましたがforeach、これは改善です。
サービー2017

1
@Servyということです。元の回答からの単一の反復に加えて、私はラムダを避けています。
Fabricio Godoy 2017

7

イテレータ実装はそれを提供しません。あなたのコレクションはIList、O(1)のインデックスを介してアクセスできるものである可能性があります。その場合は、通常のforループを使用できます。

for(int i = 0; i < Model.Results.Count; i++)
{
  if(i == Model.Results.Count - 1) doMagic();
}

あなたは、カウントを知っているが、指標(したがって、結果は経由でのアクセスができない場合ICollection)、あなたはインクリメントすることにより、自分自身をカウントすることができますiforeachのボディと長さとの比較します。

これらすべては完全にエレガントではありません。クリスの解決策は、私がこれまで見てきた中で最も優れているかもしれません。


foreachアイデアとChrisのソリューション内のカウンターのパフォーマンスを比較すると、1回のLast()呼び出し、または追加されたすべてのインクリメントオペレーションの合計のどちらがよりコストがかかるのでしょうか。近いと思う。
TTT 2014年

6

少し単純なアプローチについてはどうでしょう。

Item last = null;
foreach (Item result in Model.Results)
{
    // do something with each item

    last = result;
}

//Here Item 'last' contains the last object that came in the last of foreach loop.
DoSomethingOnLastElement(last);

2
誰かがあなたに反対票を投じた理由がわかりません。これは、すでにforeachを実行していて、o(n)のコストが発生していることを考えると、まったく問題ありません。
arviman 2015

2
答えが最後の項目を見つけるのに最適であるという事実にもかかわらず、それはOPの条件に適合しません " ...、ループの最後の反復であるかを決定してください "。したがって、最後の反復が実際に最後の反復であると判断することができず、したがって、それを別の方法で処理したり、無視したりすることもできませんでした。それが誰かがあなたに反対票を投じた理由です。@arvimanあなたはそれについてとても興味を持っていました。
AlexMelw 2018年

1
そうです、@ Andrey-WDには完全に会いたかったです。私は修正に対する解決策は、ループの前に一度「最後」と呼ぶ(これはO(N ^ 2となるように、ループ内でそれを行うことはできません)、その後、参照はそれと一致するかどうかを確認することであると思います。
arviman

5

最善のアプローチはおそらく、ループの後にそのステップを実行することです:例

foreach(Item result in Model.Results)
{
   //loop logic
}

//Post execution logic

または、最後の結果に対して何かをする必要がある場合

foreach(Item result in Model.Results)
{
   //loop logic
}

Item lastItem = Model.Results[Model.Results.Count - 1];

//Execute logic on lastItem here

3

受け入れられた回答は、コレクション内の重複に対しては機能しません。に設定されているforeach場合は、独自のインデックス変数を追加できます。

int last = Model.Results.Count - 1;
int index = 0;
foreach (Item result in Model.Results)
{
    //Do Things

    if (index == last)
        //Do Things with the last result

    index++;
}


1

「.Last()」は機能しなかったので、次のようにしなければなりませんでした。

Dictionary<string, string> iterativeDictionary = someOtherDictionary;
var index = 0;
iterativeDictionary.ForEach(kvp => 
    index++ == iterativeDictionary.Count ? 
        /*it's the last item */ :
        /*it's not the last item */
);

1

Jon Skeetの優れたコードに少し調整を加えると、前のアイテムと次のアイテムへのアクセスを許可することで、さらにスマートにすることができます。もちろん、これは実装の1つの項目を先読みする必要があることを意味します。パフォーマンス上の理由から、前のアイテムと次のアイテムは現在の反復アイテムでのみ保持されます。こんなふうになります:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// Based on source: http://jonskeet.uk/csharp/miscutil/

namespace Generic.Utilities
{
    /// <summary>
    /// Static class to make creation easier. If possible though, use the extension
    /// method in SmartEnumerableExt.
    /// </summary>
    public static class SmartEnumerable
    {
        /// <summary>
        /// Extension method to make life easier.
        /// </summary>
        /// <typeparam name="T">Type of enumerable</typeparam>
        /// <param name="source">Source enumerable</param>
        /// <returns>A new SmartEnumerable of the appropriate type</returns>
        public static SmartEnumerable<T> Create<T>(IEnumerable<T> source)
        {
            return new SmartEnumerable<T>(source);
        }
    }

    /// <summary>
    /// Type chaining an IEnumerable&lt;T&gt; to allow the iterating code
    /// to detect the first and last entries simply.
    /// </summary>
    /// <typeparam name="T">Type to iterate over</typeparam>
    public class SmartEnumerable<T> : IEnumerable<SmartEnumerable<T>.Entry>
    {

        /// <summary>
        /// Enumerable we proxy to
        /// </summary>
        readonly IEnumerable<T> enumerable;

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="enumerable">Collection to enumerate. Must not be null.</param>
        public SmartEnumerable(IEnumerable<T> enumerable)
        {
            if (enumerable == null)
            {
                throw new ArgumentNullException("enumerable");
            }
            this.enumerable = enumerable;
        }

        /// <summary>
        /// Returns an enumeration of Entry objects, each of which knows
        /// whether it is the first/last of the enumeration, as well as the
        /// current value and next/previous values.
        /// </summary>
        public IEnumerator<Entry> GetEnumerator()
        {
            using (IEnumerator<T> enumerator = enumerable.GetEnumerator())
            {
                if (!enumerator.MoveNext())
                {
                    yield break;
                }
                bool isFirst = true;
                bool isLast = false;
                int index = 0;
                Entry previous = null;

                T current = enumerator.Current;
                isLast = !enumerator.MoveNext();
                var entry = new Entry(isFirst, isLast, current, index++, previous);                
                isFirst = false;
                previous = entry;

                while (!isLast)
                {
                    T next = enumerator.Current;
                    isLast = !enumerator.MoveNext();
                    var entry2 = new Entry(isFirst, isLast, next, index++, entry);
                    entry.SetNext(entry2);
                    yield return entry;

                    previous.UnsetLinks();
                    previous = entry;
                    entry = entry2;                    
                }

                yield return entry;
                previous.UnsetLinks();
            }
        }

        /// <summary>
        /// Non-generic form of GetEnumerator.
        /// </summary>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        /// <summary>
        /// Represents each entry returned within a collection,
        /// containing the value and whether it is the first and/or
        /// the last entry in the collection's. enumeration
        /// </summary>
        public class Entry
        {
            #region Fields
            private readonly bool isFirst;
            private readonly bool isLast;
            private readonly T value;
            private readonly int index;
            private Entry previous;
            private Entry next = null;
            #endregion

            #region Properties
            /// <summary>
            /// The value of the entry.
            /// </summary>
            public T Value { get { return value; } }

            /// <summary>
            /// Whether or not this entry is first in the collection's enumeration.
            /// </summary>
            public bool IsFirst { get { return isFirst; } }

            /// <summary>
            /// Whether or not this entry is last in the collection's enumeration.
            /// </summary>
            public bool IsLast { get { return isLast; } }

            /// <summary>
            /// The 0-based index of this entry (i.e. how many entries have been returned before this one)
            /// </summary>
            public int Index { get { return index; } }

            /// <summary>
            /// Returns the previous entry.
            /// Only available for the CURRENT entry!
            /// </summary>
            public Entry Previous { get { return previous; } }

            /// <summary>
            /// Returns the next entry for the current iterator.
            /// Only available for the CURRENT entry!
            /// </summary>
            public Entry Next { get { return next; } }
            #endregion

            #region Constructors
            internal Entry(bool isFirst, bool isLast, T value, int index, Entry previous)
            {
                this.isFirst = isFirst;
                this.isLast = isLast;
                this.value = value;
                this.index = index;
                this.previous = previous;
            }
            #endregion

            #region Methods
            /// <summary>
            /// Fix the link to the next item of the IEnumerable
            /// </summary>
            /// <param name="entry"></param>
            internal void SetNext(Entry entry)
            {
                next = entry;
            }

            /// <summary>
            /// Allow previous and next Entry to be garbage collected by setting them to null
            /// </summary>
            internal void UnsetLinks()
            {
                previous = null;
                next = null;
            }

            /// <summary>
            /// Returns "(index)value"
            /// </summary>
            /// <returns></returns>
            public override string ToString()
            {
                return String.Format("({0}){1}", Index, Value);
            }
            #endregion

        }
    }
}

1

foreach最後の要素に反応するように変換する方法:

List<int> myList = new List<int>() {1, 2, 3, 4, 5};
Console.WriteLine("foreach version");
{
    foreach (var current in myList)
    {
        Console.WriteLine(current);
    }
}
Console.WriteLine("equivalent that reacts to last element");
{
    var enumerator = myList.GetEnumerator();
    if (enumerator.MoveNext() == true) // Corner case: empty list.
    {
        while (true)
        {
            int current = enumerator.Current;

            // Handle current element here.
            Console.WriteLine(current);

            bool ifLastElement = (enumerator.MoveNext() == false);
            if (ifLastElement)
            {
                // Cleanup after last element
                Console.WriteLine("[last element]");
                break;
            }
        }
    }
    enumerator.Dispose();
}

1

以前の値を保存して、ループ内で処理するだけです。次に、最後に「前の」値が最後のアイテムになり、別の方法で処理できます。カウントや特別なライブラリは必要ありません。

bool empty = true;
Item previousItem;

foreach (Item result in Model.Results)
{
    if (!empty)
    {
        // We know this isn't the last item because it came from the previous iteration
        handleRegularItem(previousItem);
    }

    previousItem = result;
    empty = false;
}

if (!empty)
{
    // We know this is the last item because the loop is finished
    handleLastItem(previousItem);
}

1

forループを使用するだけでiffor本体内に余分なものを追加する必要はありません。

for (int i = 0; i < Model.Results.Count - 1; i++) {
    var item = Model.Results[i];
}

条件は、最後の項目をスキップの世話をします。-1for


forループの-1は、最後の項目のスキップを処理しません。-1を含めなかった場合、IndexOutOfRangeExceptionが発生します。
Jaa H


0

最後の要素以外の各要素に何かを行うには、関数ベースのアプローチを使用できます。

delegate void DInner ();

....
    Dinner inner=delegate 
    { 
        inner=delegate 
        { 
            // do something additional
        } 
    }
    foreach (DataGridViewRow dgr in product_list.Rows)
    {
        inner()
        //do something
    }
}

このアプローチには明らかな欠点があります。より複雑なケースではコードがわかりにくくなります。デリゲートを呼び出すことはあまり効果的ではないかもしれません。トラブルシューティングは簡単ではないかもしれません。明るい面-コーディングは楽しいです!

そうは言っても、コレクションのカウントがそれほど遅くないことがわかっている場合は、些細なケースでは単純なforループを使用することをお勧めします。


0

投稿が表示されなかった別の方法は、キューを使用することです。これは、必要以上に繰り返すことなくSkipLast()メソッドを実装する方法に似ています。この方法では、最後のアイテムの任意の数でこれを行うこともできます。

public static void ForEachAndKnowIfLast<T>(
    this IEnumerable<T> source,
    Action<T, bool> a,
    int numLastItems = 1)
{
    int bufferMax = numLastItems + 1;
    var buffer = new Queue<T>(bufferMax);
    foreach (T x in source)
    {
        buffer.Enqueue(x);
        if (buffer.Count < bufferMax)
            continue; //Until the buffer is full, just add to it.
        a(buffer.Dequeue(), false);
    }
    foreach (T item in buffer)
        a(item, true);
}

これを呼び出すには、次のようにします。

Model.Results.ForEachAndKnowIfLast(
    (result, isLast) =>
    {
        //your logic goes here, using isLast to do things differently for last item(s).
    });

0
     List<int> ListInt = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };


                int count = ListInt.Count;
                int index = 1;
                foreach (var item in ListInt)
                {
                    if (index != count)
                    {
                        Console.WriteLine("do something at index number  " + index);
                    }
                    else
                    {
                        Console.WriteLine("Foreach loop, this is the last iteration of the loop " + index);
                    }
                    index++;

                }
 //OR
                int count = ListInt.Count;
                int index = 1;
                foreach (var item in ListInt)
                {
                    if (index < count)
                    {
                        Console.WriteLine("do something at index number  " + index);
                    }
                    else
                    {
                        Console.WriteLine("Foreach loop, this is the last iteration of the loop " + index);
                    }
                    index++;

                }

0

これに特化した拡張メソッドを作成できます。

public static class EnumerableExtensions {
    public static bool IsLast<T>(this List<T> items, T item)
        {
            if (items.Count == 0)
                return false;
            T last = items[items.Count - 1];
            return item.Equals(last);
        }
    }

次のように使用できます:

foreach (Item result in Model.Results)
{
    if(Model.Results.IsLast(result))
    {
        //do something in the code
    }
}

0

@Shimmyの応答に基づいて、私は誰もが望むソリューションである拡張メソッドを作成しました。シンプルで使いやすく、コレクションをループするのは1回だけです。

internal static class EnumerableExtensions
{
    public static void ForEachLast<T>(this IEnumerable<T> collection, Action<T>? actionExceptLast = null, Action<T>? actionOnLast = null)
    {
        using var enumerator = collection.GetEnumerator();
        var isNotLast = enumerator.MoveNext();
        while (isNotLast)
        {
            var current = enumerator.Current;
            isNotLast = enumerator.MoveNext();
            var action = isNotLast ? actionExceptLast : actionOnLast;
            action?.Invoke(current);
        }
    }
}

これはどのでも機能しますIEnumerable<T>。使用法は次のようになります。

var items = new[] {1, 2, 3, 4, 5};
items.ForEachLast(i => Console.WriteLine($"{i},"), i => Console.WriteLine(i));

出力は次のようになります。

1,
2,
3,
4,
5

さらに、これをSelectスタイルメソッドにすることができます。次に、その拡張機能をで再利用しForEachます。そのコードは次のようになります。

internal static class EnumerableExtensions
{
    public static void ForEachLast<T>(this IEnumerable<T> collection, Action<T>? actionExceptLast = null, Action<T>? actionOnLast = null) =>
        // ReSharper disable once IteratorMethodResultIsIgnored
        collection.SelectLast(i => { actionExceptLast?.Invoke(i); return true; }, i => { actionOnLast?.Invoke(i); return true; }).ToArray();

    public static IEnumerable<TResult> SelectLast<T, TResult>(this IEnumerable<T> collection, Func<T, TResult>? selectorExceptLast = null, Func<T, TResult>? selectorOnLast = null)
    {
        using var enumerator = collection.GetEnumerator();
        var isNotLast = enumerator.MoveNext();
        while (isNotLast)
        {
            var current = enumerator.Current;
            isNotLast = enumerator.MoveNext();
            var selector = isNotLast ? selectorExceptLast : selectorOnLast;
            //https://stackoverflow.com/a/32580613/294804
            if (selector != null)
            {
                yield return selector.Invoke(current);
            }
        }
    }
}

-1

ループ内の最後のアイテムをチェックできます。

foreach (Item result in Model.Results)
{
    if (result==Model.Results.Last())
    {
        // do something different with the last item
    }
}

-2
foreach (DataRow drow in ds.Tables[0].Rows)
            {
                cnt_sl1 = "<div class='col-md-6'><div class='Slider-img'>" +
                          "<div class='row'><img src='" + drow["images_path"].ToString() + "' alt='' />" +
                          "</div></div></div>";
                cnt_sl2 = "<div class='col-md-6'><div class='Slider-details'>" +
                          "<p>" + drow["situation_details"].ToString() + "</p>" +
                          "</div></div>";
                if (i == 0)
                {
                    lblSituationName.Text = drow["situation"].ToString();
                }
                if (drow["images_position"].ToString() == "0")
                {
                    content += "<div class='item'>" + cnt_sl1 + cnt_sl2 + "</div>";
                    cnt_sl1 = "";
                    cnt_sl2 = "";
                }
                else if (drow["images_position"].ToString() == "1")
                {
                    content += "<div class='item'>" + cnt_sl2 + cnt_sl1 + "</div>";
                    cnt_sl1 = "";
                    cnt_sl2 = "";
                }
                i++;
            }

(!)コードがどれほど良いか悪いかに関係なく。説明がなければ、それは通常価値がありません。
AlexMelw 2018年

また、それはかなり過剰に設計されているようです。
mecograph

-3

あなたはこのようにすることができます:

foreach (DataGridViewRow dgr in product_list.Rows)
{
    if (dgr.Index == dgr.DataGridView.RowCount - 1)
    {
        //do something
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.