获取队列中的下一个值

时间:2015-04-06 20:31:57

标签: c# foreach queue

今天我遇到了一个队列变量的问题,我试着读入并获取队列中的下一个对象。我正在使用一个遍历队列中所有对象的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;
            }
        }
    }

2 个答案:

答案 0 :(得分:2)

听起来好像在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);
    }
}

答案 1 :(得分:0)

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

这里说的有两种方法可以用Queue来完成你想要的工作。

  1. &#39; Destructive&#39;方式是Queue应该被使用的方式,你随身携带Dequeue()项目。在你提前Dequeue() Peek()后,要实现您的目标。请注意,如果Queue中没有任何内容,则两个函数都会抛出异常。你可以通过多种方式为这只猫提供皮肤。您可以在Count循环中每次迭代后获得while(),或者像我在下面显示的for循环一样。我选择后者用于这个具体案例,因为你也在偷看,通常我会使用while循环。
  2. 如果您遇到了Queue,但这只是一个您正在调用的中间函数,必须保持队列不变,且不能Dequeue()项,我添加了一个非破坏性的版本使用枚举器。请注意在签名中使用IEnumerable。这将使其与其他实现此接口的集合一起使用,并且不仅限于Queue,因为您没有使用Queue功能。
  3. 以下是代码示例,它会在控制台上为每次迭代打印一些内容,但是您可以看到将代码放在最后的位置。迭代案例。

    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());
                }
            }
        }
    

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