ফরচ লুপ, লুপের শেষ পুনরাবৃত্তিটি নির্ধারণ করুন


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
 }

লুপ এবং কাউন্টার ব্যবহার না করে কোন লুপটি শেষ তা জানতে পারি?


1
সম্পর্কিত প্রশ্নটিতে পোস্ট করা একটি সমাধানের জন্য আমার উত্তরটি এখানে দেখুন ।
ব্রায়ান গিডন

উত্তর:


294

যদি আপনাকে শেষ উপাদানটির সাথে কিছু করার দরকার হয় (শেষ উপাদানটির সাথে আলাদা কিছু করার বিপরীতে লিনকিউ ব্যবহার করা এখানে সহায়তা করবে:

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
আমার যা দরকার ছিল তা হল: যখন লুপটি তার শেষ আইটেমটি গ্রূপ করছে: ভবিষ্যদ্বাণী (আইটেমের ফলস্বরূপ মডেল) ফলাফল) {যদি (ফলাফল == মডেল। ফলাফল L শেষ ()) d <ডিআইভি> সর্বশেষ </ div>; } মনে হচ্ছে আপনি প্রায় একই জিনিস বোঝাতে চেয়েছিলেন।
দুর্ঘটনা

10
আপনার কোডটি পুরো সংগ্রহের মাধ্যমে দ্বিগুণ হবে - সংগ্রহটি ছোট না হলে খারাপ isn't এই উত্তর দেখুন ।
শিমি ওয়েটজ্যান্ডলার

54
আপনার সংগ্রহে ডুপ্লিকেট থাকলে এটি সত্যিই কাজ করে না। উদাহরণস্বরূপ, আপনি যদি স্ট্রিংয়ের সংকলন নিয়ে কাজ করছেন এবং কোনও নকল রয়েছে, তবে সেই "শেষ আইটেমের সাথে আলাদা" কোডটি তালিকার সর্বশেষ আইটেমের প্রতিটি ঘটনার জন্য কার্যকর করা হবে।
muttley91

7
এই উত্তরটি পুরানো, তবে অন্যদের এই উত্তরটি দেখার জন্য, আপনি সর্বশেষ উপাদানটি পেতে পারেন এবং নিশ্চিত করতে পারেন যে আপনাকে উপাদানগুলি ব্যবহার করে লুপ করতে হবে না: আইটেম লাস্ট = মডেল es ফলাফল [মডেল es ফলাফল.কাউন্ট - 1] গণনা একটি তালিকার সম্পত্তি লুপিং প্রয়োজন হয় না। আপনার তালিকায় যদি সদৃশ থাকে তবে লুপের জন্য কেবল একটি পুনরাবৃত্তাকার ভেরিয়েবল ব্যবহার করুন। লুপগুলির জন্য নিয়মিত পুরানো খারাপ নয়।
মাইকেল হ্যারিস

আমি ব্যবহার সুপারিশ var last = Model.Result[Model.Result.Count - 1];দ্রুত ব্যবহার না করে এর জন্যLast()
Tân

184

লুপের জন্য কীভাবে একটি ভাল পুরানো ফ্যাশন সম্পর্কে?

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

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

বা লিনক এবং ভবিষ্যদ্বাণী ব্যবহার:

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

14
অনেক পিপিএল এ জাতীয় কোনও সাধারণ সমস্যাটিকে ওভারথিংক করে যখন লুপের জন্য ইতিমধ্যে এটি করার জন্য পুরোপুরি সক্ষম হয়। : \
অ্যান্ড্রু হফম্যান

লিনক সমাধানটি আমার পরম প্রিয়! ভাগ করে নেওয়ার জন্য ধন্যবাদ
মেকোগ্রাফ

এটি গৃহীত উত্তরটির চেয়ে উপযুক্ত উত্তর।
রাতুল

স্ট্রিংয়ের সংগ্রহ (বা মানের ধরণ )গুলিতে লিনকিউ সমাধানটি ব্যবহার করতে ইচ্ছুককে নোট করুন: এটি সাধারণত কাজ করবে না কারণ == তুলনা ব্যর্থ হবে যদি তালিকার শেষ স্ট্রিংটিও তালিকার আগে প্রদর্শিত হয়। এটি কেবল তখনই কাজ করবে যদি আপনি কোনও নকল স্ট্রিং না থাকার গ্যারান্টিযুক্ত তালিকার সাথে কাজ করছেন।
তাওয়াব ওয়াকিল

দুর্ভাগ্যক্রমে আপনি যদি এই চতুর সমাধানটি ব্যবহার করতে পারেন তবে Model.Resultsএটি একটি IEnumerable। আপনি Count()লুপের আগে কল করতে পারেন তবে এটি ক্রমের পুরো পুনরাবৃত্তির কারণ হতে পারে।
লুকা ক্রেমনেসি

42

Last()নির্দিষ্ট ধরণের উপর ব্যবহার করে পুরো সংগ্রহটি লুপ হয়ে যাবে!
এর অর্থ হ'ল আপনি যদি foreachকল করেন এবং কল করেন Last(), আপনি দুবার লুপ করেছেন! যা আমি নিশ্চিত আপনি বড় সংগ্রহগুলি এড়াতে চাই।

তারপরে সমাধানটি একটি 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()

পরীক্ষা

যদি আপনার সংগ্রহটি এলোমেলো অ্যাক্সেস সরবরাহ করে (উদাহরণস্বরূপ সরঞ্জামগুলি IList<T>), আপনি নিম্নলিখিত হিসাবে আপনার আইটেমটিও পরীক্ষা করতে পারেন।

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

1
আপনি কি নিশ্চিত যে গণকের একটি usingবিবৃতি প্রয়োজন? আমি ভেবেছিলাম এটি কেবল তখনই প্রয়োজন যখন কোনও বস্তু অপারেটিং সিস্টেমের রিসোর্সগুলি পরিচালনা করে তবে পরিচালিত ডেটা স্ট্রাকচারের জন্য নয়।
বিড়ালছানা

আইনিউমরেটর আইডিস্পোজেবল বাস্তবায়ন করে না, সুতরাং একটি সংকলন সময় ত্রুটি বাড়াতে ব্যবহার করে লাইন! সমাধানের জন্য +1, বেশিরভাগ সময় আমরা কেবল পূর্বাভাসের পরিবর্তে কেবল একটি ব্যবহার করতে পারি না, কারণ প্রচুর সংগ্রহের আইটেমগুলি রানটাইমের সময় গণনা করে বা ক্রমটি এলোমেলো অ্যাক্সেসকে সমর্থন করে না।
সালেহ


40

ক্রিস যেমন দেখায়, লিনক কাজ করবেন; কেবল গণনার ক্ষেত্রে শেষের একটি রেফারেন্স পেতে শেষ () ব্যবহার করুন এবং যতক্ষণ আপনি সেই উল্লেখের সাথে কাজ করছেন না ততক্ষণ আপনার স্বাভাবিক কোডটি করুন, তবে আপনি যদি সেই রেফারেন্স নিয়ে কাজ করছেন তবে আপনার অতিরিক্ত জিনিসটি করুন। এর খারাপ দিকটি হ'ল এটি সর্বদা ও (এন) -কম্প্লেসিটি হবে।

পরিবর্তে আপনি গণনা () (যা ও (1) ব্যবহার করতে পারেন যদি আইনামেবারেবলও একটি আইকোলিকেশন হয়; এটি বেশিরভাগ সাধারণ অন্তর্নির্মিত আইমনামেবার্সের ক্ষেত্রে সত্য), এবং একটি কাউন্টার সহ আপনার ভবিষ্যদ্বাণীকে সংকর করুন:

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))
  {

  }
}

হ্যালো, এটি এখন পর্যন্ত সেরা পদ্ধতির! সহজ এবং যথাযথ. একটি প্রোগ্রামার-টকিং পদ্ধতির, একটি one কেন আমরা এইটিকে আরও 1+ বাছুন এবং দেই না!
হ্যানি Setiawan

1
শেষ আইটেমটি ব্লক হওয়ার আগে একবারেই ( স্মৃতিচারণ প্রচার করুন ) খুঁজে পাওয়া উচিত foreach। ভালো: var lastItem = objList.LastOrDeafault();। তারপর ভিতর থেকে foreachলুপ আপনি এটি এই ভাবে পরীক্ষা পারে: f (item.Equals(lastItem)) { ... }। আপনার মূল উত্তরে objList.LastOrDefault()প্রতিটি " ফোরচ " পুনরাবৃত্তিতে সংগ্রহের মাধ্যমে পুনরাবৃত্তি হবে ( বহু বহু জটিলতা জড়িত )।
অ্যালেক্সমেলউ

খারাপ উত্তর। n এর পরিবর্তে n ^ 2 জটিলতা।
শিমি ওয়েটজ্যান্ডলার

11

শিমি যেমন উল্লেখ করেছে, শেষ () ব্যবহার করা একটি পারফরম্যান্স সমস্যা হতে পারে, উদাহরণস্বরূপ যদি আপনার সংগ্রহটি কোনও লিনকিউ এক্সপ্রেশনটির লাইভ ফলাফল হয়। একাধিক পুনরাবৃত্তি রোধ করতে আপনি "ফোরএচ" এক্সটেনশন পদ্ধতিটি এর মতো ব্যবহার করতে পারেন:

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যেমন একাধিক পুনরাবৃত্তিও এবং lambdas এড়াতে:

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
অন্য উত্তরটি উত্সটি একাধিকবার পুনরাবৃত্তি করে না, সুতরাং এটি ঠিক করা কোনও সমস্যা নয়। আপনি প্রকৃতপক্ষে ব্যবহারের অনুমতি দিয়েছেন foreach, যা একটি উন্নতি।
পরিবেশন করুন

1
@ সার্ভে আমার মানে আসল উত্তর থেকে একক পুনরাবৃত্তি ছাড়াও আমি ল্যাম্বডাস এড়িয়ে চলেছি।
ফ্যাব্রিকিও গডয়

7

পুনরুক্তি বাস্তবায়ন এটি সরবরাহ করে না। আপনার সংগ্রহটি এমন কোনও হতে পারে IListযা হে (1) এর সূচকের মাধ্যমে অ্যাক্সেসযোগ্য। forসেক্ষেত্রে আপনি একটি সাধারণ- লুপ ব্যবহার করতে পারেন :

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

আপনি COUNT জানি, কিন্তু সূচকের (সুতরাং, ফলে একটি হল মাধ্যমে অ্যাক্সেস করতে না পারেন ICollection), আপনি নিজেকে একজন বৃদ্ধিশীল দ্বারা নির্ভর করতে পারেন iমধ্যে foreachএর শরীর ও দৈর্ঘ্যের তুলনা।

এগুলি পুরোপুরি মার্জিত নয়। ক্রিসের সমাধানটি আমি এখনও অবধি দেখলাম নিস্ট।


ভবিষ্যতের পরিকল্পনা বনাম ক্রিসের সমাধানের মধ্যে আপনার কাউন্টারের পারফরম্যান্সের তুলনায়, আমি অবাক হই যে এর জন্য আরও বেশি দাম পড়বে- একটি একক শেষ () কল, বা সমস্ত যুক্ত বর্ধিত ক্রিয়াকলাপের যোগফল। আমার সন্দেহ হয় এটি খুব কাছাকাছি হবে।
টিটিটি

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
আমি জানি না কেন কেউ আপনাকে ভোট দিয়েছে। আপনি ইতিমধ্যে একটি ভবিষ্যদ্বাণী করছেন এবং ও (এন) এর ব্যয় বহন করছেন বিবেচনা করে এটি পুরোপুরি গ্রহণযোগ্য।
আরভিমান

2
উত্তরটি সর্বশেষ আইটেমটি সন্ধানের জন্য উপযুক্ত, তবুও এটি ওপি'র শর্তের সাথে খাপ খায় না ... " , লুপের শেষ পুনরাবৃত্তি কোনটি " তা নির্ধারণ করে । সুতরাং, আপনি নির্ধারণ করতে সক্ষম নন যে শেষ পুনরাবৃত্তিটি আসলে শেষটি, এবং এইভাবে, আপনি এটি অন্যভাবে পরিচালনা করতে পারেন না এমনকি এটিকে উপেক্ষাও করতে পারেন না। যে কারণে কেউ আপনাকে হ্রাস করেছে। @ আরভিমান আপনি এটি সম্পর্কে খুব কৌতূহলী ছিলেন।
অ্যালেক্সমেলউ

1
আপনি ঠিক বলেছেন, আমি এটি @ অ্যান্ড্রে-ডাব্লুডি পুরোপুরি মিস করেছি। আমি ফিক্স সমাধান যেমন যদি রেফারেন্স মিলবে হে (ঢ ^ 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++;
}

2

লিনক এবং ভবিষ্যদ্বাণী ব্যবহার:

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

https://code.i-harness.com/en/q/7213ce


1
তালিকা / সংগ্রহের অনন্য মান থাকলে এটি কেবলমাত্র কাজ করবে।
মেল্লেক

1

"। সর্বশেষ ()" আমার পক্ষে কাজ করে নি, তাই আমাকে এরকম কিছু করতে হয়েছিল:

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

জন স্কিটির দুর্দান্ত কোডটিতে কিছুটা ছোট সামঞ্জস্য করা, আপনি আগের এবং পরবর্তী আইটেমটিতে অ্যাক্সেসের মাধ্যমে এটি আরও চৌকস করতে পারেন। অবশ্যই এর অর্থ আপনাকে বাস্তবায়নে 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

আপনি কেবল লুপের জন্য একটি ব্যবহার করতে পারেন ifএবং forদেহের অভ্যন্তরে কোনও অতিরিক্ত যুক্ত করার দরকার নেই :

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

-1মধ্যে forশর্ত শেষ আইটেম কুঁদন যত্ন নেয়।


লুপের জন্য -1 সর্বশেষ আইটেমটি এড়িয়ে যাওয়ার যত্ন নেয় না। আপনি যদি -1 অন্তর্ভুক্ত না করেন তবে আপনি একটি সূচকআউটআফরেঞ্জএক্সসেপশন পাবেন।
জাএ এইচ

0

SmartEnumerable<T>এই সঠিক সমস্যাটি সমাধান করতে কিছুক্ষণ আগে জেন স্কিইট একটি প্রকার তৈরি করেছিলেন । আপনি এখানে এটি বাস্তবায়ন দেখতে পারেন:

http://codeblog.jonskeet.uk/2007/07/27/smart-enumerations/

ডাউনলোড করতে: http://www.yoda.arachsys.com/csharp/miscutil/


0

শেষটি ব্যতীত প্রতিটি উপাদানকে অতিরিক্ত কিছু করার জন্য, ফাংশন ভিত্তিক পদ্ধতির ব্যবহার করা যেতে পারে।

delegate void DInner ();

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

এই পদ্ধতির স্পষ্ট ত্রুটি রয়েছে: আরও জটিল ক্ষেত্রে কম কোড স্পষ্টতা। প্রতিনিধিদের কল করা খুব কার্যকর নাও হতে পারে। সমস্যার সমাধান খুব সহজ নাও হতে পারে। উজ্জ্বল দিক - কোডিং মজা!

এটি বলার পরে, আমি তুচ্ছ মামলায় লুপের জন্য সরল ব্যবহারের পরামর্শ দেব, যদি আপনি জানেন যে আপনার সংগ্রহে গণনাটি ভীষণ ধীর নয়।


0

আর একটি উপায়, যা আমি পোস্ট দেখিনি, তা হল একটি সারি ব্যবহার করা। এটি প্রয়োজনের চেয়ে বেশি বারবার ছাড়াই স্কিপলাস্ট () পদ্ধতি প্রয়োগের উপায়ের সাথে উপমা। এই উপায় আপনাকে শেষ আইটেমের যে কোনও সংখ্যাতে এটি করার অনুমতি দেবে।

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

@ শিমির প্রতিক্রিয়াটির ভিত্তিতে, আমি একটি এক্সটেনশন পদ্ধতি তৈরি করেছি যা এটিই সমাধানের সমাধান যা প্রত্যেকে চায়। এটি সহজ, ব্যবহার করা সহজ এবং একবারে সংগ্রহের মধ্য দিয়ে কেবল লুপ হয়।

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++;
            }

(!) আপনার কোডটি কতটা ভাল বা খারাপ হোক তা বিবেচনা করুন। ব্যাখ্যা ব্যতীত এর সাধারণত কোনও মূল্য থাকে না।
অ্যালেক্সমেলউ

এছাড়াও এটি ওভার ইঞ্জিনিয়ারড মনে হয়।
মেকোগ্রাফ

-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.