正在获取队列中的下一个值



我今天遇到了一个队列变量的问题,我正试图读入该变量并获取队列中的下一个对象。我使用的foreach循环遍历队列中的所有对象。但我也想找出下一个对象的值,这就是我被卡住的地方。这是我迄今为止完成的代码。

private static void outResult(Queue<OrderClass> orderQueue)
    {
        int week = 0;
        int orderCount = 0;
        bool last = false;
        foreach(OrderClass n in orderQueue)
        {
            week = n.DesiredWeek;
            if(week != n.NextWeek)//This is what i want to do
            {
                last = true;
            }
            if(last)
            {
                Console.WriteLine("Shipping Report for Week {0}", week);
                Console.WriteLine(" ");
                Console.WriteLine("Number of Orders: {0}");
                Console.WriteLine(" ");
                Console.WriteLine("Products shipped: ");
                Console.WriteLine("Cabin:  ");
                Console.WriteLine("LarghFort:  ");
                Console.WriteLine("Ranch:  ");
                Console.WriteLine("Shed:  ");
                Console.WriteLine("SmallHouse:  ");
                Console.WriteLine("Tower:  ");
                Console.WriteLine(" ");
                last = false;
            }
        }
    }

这听起来像是在for循环中,你想在不删除它的情况下查看队列中的下一个值。如果这是正确的,你想使用的是

var next = orderQueue.Peek();
if(week != next.DesiredWeek){
    // do stuff
}

编辑:对于您的用例,我的原始示例是不完整的。您还需要修改迭代的方式,因为foreach迭代实际上并没有弹出元素。有关更完整的示例,请参见下文。

var queue = new Queue<int>();
queue.Enqueue(1);
queue.Enqueue(2);
while(queue.Count > 0 )
{
    var val = queue.Dequeue();
    Console.WriteLine("Current: {0}", val);
    if(queue.Count > 0)
    {
        var next = queue.Peek();
        Console.WriteLine("Next: {0}", next);
    }
}

我认为Queue<T>不是您正在执行的操作的正确结构。看起来更像是List<T>的情况,因为您没有从Queue中取出任何元素。

话虽如此,这里有两种方法可以用Queue做你想要的事情。

  1. "破坏性"方式是Queue的使用方式,即在进行过程中Dequeue()项目。为了实现你想要的,在你Dequeue()之后,你Peek()领先。请注意,如果Queue中没有剩余内容,那么这两个函数都会抛出异常。有多种方法可以剥这只猫的皮。要么在while()循环中的每次迭代后得到Count,要么像我下面展示的那样,用for循环只得到一次。对于这个特定的情况,我选择了后面的,因为你也在向前看,通常我会使用while循环
  2. 如果您一直使用Queue,但这只是您正在调用的一个中间函数,必须保持队列不变,并且不能使用Dequeue()项,那么我添加了一个仅使用枚举器的非破坏性版本。请注意签名中使用了IEnumerable。这将使它与实现该接口的其他集合一起工作,并且不限于Queue,因为您没有使用Queue功能

这是一个代码示例,它为每次迭代在控制台上打印一些内容,但您可以看到您将为"最后"迭代案例放置代码的位置。

class Program
{
    static void Main(string[] args)
    {
        Queue<OrderClass> orderQueue = new Queue<OrderClass>();
        for (int i = 0; i < 10; i++)
        {
            orderQueue.Enqueue(new OrderClass() { DesiredWeek = (i / 3) });
        }
        outResultNonDestructive(orderQueue);
        outResultDestructive(orderQueue);
    }
    public class OrderClass
    {
        public int DesiredWeek { get; set; }
    }
    private static void outResultDestructive(Queue<OrderClass> orderQueue)
    {
        bool last = false;
        int lengthOfQInTheBeginning = orderQueue.Count;
        for (int i = 0; i < lengthOfQInTheBeginning; i++)
        {
            var current = orderQueue.Dequeue();
            if(i >= lengthOfQInTheBeginning - 1)
            {
                last = true;
            }
            else
            {
                var next = orderQueue.Peek();
                if(current.DesiredWeek != next.DesiredWeek)
                {
                    last = true;
                }
            }
            if (last)
            {
                //Do work...
                Console.WriteLine(current.DesiredWeek.ToString() + " - Last? " + last.ToString());
                last = false;
            }
            else
            {
                Console.WriteLine(current.DesiredWeek.ToString() + " - Last? " + last.ToString());
            }
        }
    }
    private static void outResultNonDestructive(IEnumerable<OrderClass> orderQueue)
    {
        bool last = false;
        IEnumerator<OrderClass> currentEnumerator = orderQueue.GetEnumerator();
        IEnumerator<OrderClass> nextEnumerator = orderQueue.GetEnumerator();
        if(!nextEnumerator.MoveNext())
        {
            //No elements
        }
        while(currentEnumerator.MoveNext())
        {
            OrderClass next = null;
            if(nextEnumerator.MoveNext())
            {
                next = nextEnumerator.Current;
            }
            var current = currentEnumerator.Current;
            if(next == null || current.DesiredWeek != next.DesiredWeek)
            {
                last = true;
            }
            if (last)
            {
                //Do work...
                Console.WriteLine(current.DesiredWeek.ToString() + " - Last? " + last.ToString());
                last = false;
            }
            else
            {
                Console.WriteLine(current.DesiredWeek.ToString() + " - Last? " + last.ToString());
            }
        }
    }

请注意,这两个函数都不是线程安全的!

相关内容

最新更新