亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何通過 IEnumerable 訪問 foreach 迭代中的下一個和上一個項目?

如何通過 IEnumerable 訪問 foreach 迭代中的下一個和上一個項目?

C#
陪伴而非守候 2022-11-22 16:21:12
我想在處理當前項目并迭代 時訪問下一個和上一個項目(如果在范圍內)IEnumerable<object>,它缺少索引器(據我所知)。我不想要求一個List<object>集合或一個數組來實現這一點,盡管這是我現在所知道的唯一選擇。如果可能的話,我也更愿意避免使用 Linq 表達式。目前我的方法就是這樣定義的:public static void PrintTokens(IEnumerable<object> tokens){    foreach (var token in tokens)    {        // var next = ?        // var prev = ?    }}
查看完整描述

5 回答

?
德瑪西亞99

TA貢獻1770條經驗 獲得超3個贊

您像往常一樣執行循環,但是您當前所在的項目變為next,前一個項目為current,而之前的項目為prev。


object prev = null;

object current = null;

bool first = true;

foreach (var next in tokens)

{

    if (!first)

    {

        Console.WriteLine("Processing {0}. Prev = {1}. Next = {2}", current, prev, next);

    }


    prev = current;

    current = next;

    first = false;

}


// Process the final item (if there is one)

if (!first)

{

    Console.WriteLine("Processing {0}. Prev = {1}. Next = {2}", current, prev, null);

}

如果您使用的是 C# 7.0+,則可以編寫


(prev, current, first) = (current, next, false);

而不是循環末尾的三個單獨的語句。


查看完整回答
反對 回復 2022-11-22
?
慕蓋茨4494581

TA貢獻1850條經驗 獲得超11個贊

For循環最好:


for (int i = 0; i < tokens.Count(); i++)

{

    token prv = i > 0 ? tokens[i-1] : null;

    token cur = tokens[i];

    token nxt = i < tokens.Count() ? tokens[i+1] : null;

}

然后就像你問的那樣,你可以很容易地設置循環中的當前、上一個和下一個對象變量來使用。


編輯:我想知道為什么這不是一個好的解決方案,因為它是我正在使用的。


查看完整回答
反對 回復 2022-11-22
?
慕工程0101907

TA貢獻1887條經驗 獲得超5個贊

我寫了一個擴展方法,它返回一個包含 3 個對象的元組:上一個、當前和下一個:


public static class Extensions

{

    public static IEnumerable<Tuple<T, T, T>> GetItems<T>(this IEnumerable<T> source)

        where T : class

    {

        if (source != null)

        {

            // skip the first iteration to be able to include next item

            bool skip = true;

            T previous = default(T), current = default(T), next = default(T);

            foreach (T item in source)

            {

                next = item;

                if (!skip)

                {

                    yield return new Tuple<T, T, T>(previous, current, next);

                }

                previous = current;

                current = item;

                skip = false;

            }

            if (!skip)

            {

                next = default(T);

                yield return new Tuple<T, T, T>(previous, current, next);

            }

        }

    }

}

希望能幫助到你。也許使用自定義類而不是元組進行擴展。


查看完整回答
反對 回復 2022-11-22
?
繁星點點滴滴

TA貢獻1803條經驗 獲得超3個贊

你可以試試這個擴展方法。它是獲取“大小”上一個項目和“大小”下一個項目和當前項目:


    public static System.Collections.Generic.IEnumerable<TResult> Select<TSource, TResult>(this System.Collections.Generic.IEnumerable<TSource> source, int size, System.Func<Queue<TSource>, TSource, Queue<TSource>, TResult> selector)

    {

        if (source == null)

        {

            throw new System.ArgumentNullException("source");

        }


        if (selector == null)

        {

            throw new System.ArgumentNullException("selector");

        }

        Queue<TSource> prevQueue = new Queue<TSource>(size);

        Queue<TSource> nextQueue = new Queue<TSource>(size);


        int i = 0;

        foreach (TSource item in source)

        {

            nextQueue.Enqueue(item);

            if (i++ >= size)

            {

                TSource it = nextQueue.Dequeue();

                yield return selector(prevQueue, it, nextQueue);

                prevQueue.Enqueue(it);

                if (prevQueue.Count > size)

                {

                    prevQueue.Dequeue();

                }

            }

        }


        while (nextQueue.Any())

        {

            TSource it = nextQueue.Dequeue();

            yield return selector(prevQueue, it, nextQueue);

            prevQueue.Enqueue(it);

            if (prevQueue.Count > size)

            {

                prevQueue.Dequeue();

            }

        }

    }


查看完整回答
反對 回復 2022-11-22
?
慕運維8079593

TA貢獻1876條經驗 獲得超5個贊

除非我遺漏了什么,否則 for 循環不是最簡單和最有效的方法嗎?


for (int i = 0; i < tokens.Count(); i++)

{

    token previous = i > 0 ? tokens[i - 1] : null;

    token current = tokens[i];

    token next = i < tokens.Count() ? tokens[i + 1] : null;

}

那么你當前的循環索引就是實際的循環項,previous 和 next 很容易得到,不需要“你當前的循環對象是前一個對象”,也不需要循環外單獨的'if'。


查看完整回答
反對 回復 2022-11-22
  • 5 回答
  • 0 關注
  • 150 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號