在C#中弹出数组

我在C#中有一个字符串数组,我想从数组中弹出顶部元素(即删除第一个元素,然后将所有其他元素移动一个)。 在C#中有一个简单的方法吗? 我找不到Array.Pop方法。

我需要使用像ArrayList这样的东西吗? 我的数组中项目的顺序很重要。

使用列表 , 队列或堆栈代替..

 List Queue Stack 

Queue (先进先出)或Stack (后进先出)是你所追求的。

.NET中的数组是固定长度的 – 您无法从中删除元素或者确实向它们添加元素。 您可以使用List执行此操作,但是当您需要队列/堆栈语义时, QueueStack更合适。

来自MSDN:

 using System; using System.Collections.Generic; namespace ConsoleApplication1 { class MSDNSample { static void Main() { string input = "abcd"; Stack myStack = new Stack( input.Split(new string[] { " " }, StringSplitOptions.None)); // Remove the top element (will be d!) myStack.Pop(); Queue myQueue = new Queue( input.Split(new string[] { " " }, StringSplitOptions.None)); // Remove the first element (will be a!) myQueue.Dequeue(); } } } 

http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/a924097e-3d72-439d-984a-b371cd10bcf4/

既然我们有linq很容易做到:

 string[] array = ...; array = array.Skip(1).ToArray(); 

这在Array中是完全可能的,但效率不高。 你必须使用循环向下移动数组并在for循环中设置arr [i] = arr [i + 1]。 在此之后,如果需要,您必须调整arrays的大小。

由于这些警告,数组不是处理问题的最佳数据结构。 数组最适用于静态数据或大小不会更改的数据。

由于您要删除数据,因此数组显然不是答案。 具体来说,您希望从集合中弹出第一个/ top元素,并且已经有一个高效的数据结构可以执行此操作: Stack 。

这是数据结构的美妙之处,它们为您提供了一种根据您的要求处理集合的有效方法。

我同意上述内容,但我有一点改进..

  public static class ArrayExtensions { ///  /// Removes the last element. ///  ///  /// The array. /// T[]. public static T[] RemoveLastElement(this T[] array) { var stack = new Stack(array); stack.Pop(); return stack.ToArray().Reverse().ToArray(); } ///  /// Removes the first element. ///  ///  /// The array. /// T[]. public static T[] RemoveFirstElement(this T[] array) { var queue = new Queue(array); queue.Dequeue(); return queue.ToArray(); } } 

为了完成它,这里是测试:

  [Test] public void ExtensionsTests_ArrayExtensionTests() { var data = new[] { 'A', 'B', 'C', 'D' }; Assert.AreEqual("BCD", string.Join("", data.RemoveFirstElement())); Assert.AreEqual("ABC", string.Join("", data.RemoveLastElement())); } 

我遇到了上面提到的问题,但是当集合为空时(不是特殊的情况),Queue的默认行为是抛出exception。 这是我对SafeQueue的实现,它将大多数操作推迟到基类,但实现了新的Dequeue()Peek()操作,如果队列为空,则返回default(T) 。 如果有可能将default(T)添加到队列中(对象类型不太可能,但很可能是值类型),则只能通过Peek判断队列是否为空。 新的IsEmpty属性可以告诉您什么时候完成。

 public class SafeQueue: Queue { public SafeQueue() : base() { } public SafeQueue(int count) : base(count) { } public SafeQueue(IEnumerable collection) : base(collection) { } public bool IsEmpty {get { return Count == 0; }} public new T Dequeue() { return IsEmpty ? default(T) : base.Dequeue(); } public new T Peek() { return IsEmpty ? default(T) : base.Peek(); } } [TestClass] public class SafeQueueTests { [TestMethod] public void SafeQueue_int_constructor_works() { var q = new SafeQueue(5); Assert.IsNotNull(q); Assert.AreEqual(0, q.Count); q.Enqueue("a"); Assert.AreEqual(1, q.Count); q.Enqueue("b"); Assert.AreEqual(2, q.Count); q.Enqueue("c"); Assert.AreEqual(3, q.Count); q.Enqueue("d"); Assert.AreEqual(4, q.Count); q.Enqueue("e"); Assert.AreEqual(5, q.Count); q.Enqueue("f"); Assert.AreEqual(6, q.Count); } [TestMethod] public void SafeQueue_dequeue_works() { var q = new SafeQueue(); Assert.IsNotNull(q); Assert.AreEqual(0, q.Count); q.Enqueue("a"); Assert.AreEqual(1, q.Count); q.Enqueue("b"); Assert.AreEqual(2, q.Count); var result = q.Dequeue(); Assert.AreEqual("a", result); result = q.Dequeue(); Assert.AreEqual("b", result); result = q.Dequeue(); Assert.AreEqual(null, result); } [TestMethod] public void SafeQueue_peek_works() { var q = new SafeQueue(); Assert.IsNotNull(q); Assert.AreEqual(0, q.Count); q.Enqueue("a"); Assert.AreEqual(1, q.Count); var result = q.Peek(); Assert.AreEqual("a", result); result = q.Dequeue(); Assert.AreEqual("a", result); result = q.Dequeue(); Assert.AreEqual(null, result); } [TestMethod] public void SafeQueue_isEmpty_works() { var q = new SafeQueue(); Assert.IsNotNull(q); Assert.AreEqual(0, q.Count); Assert.AreEqual(true, q.IsEmpty); q.Enqueue("content"); Assert.AreEqual(false, q.IsEmpty); var result2 = q.Dequeue(); Assert.AreEqual("content", result2); Assert.AreEqual(true, q.IsEmpty); result2 = q.Dequeue(); Assert.AreEqual(true, q.IsEmpty); Assert.AreEqual(null, result2); } [TestMethod] public void SafeQueue_passedThroughQueueOperationContains_work() { var q = new SafeQueue(5); Assert.IsNotNull(q); Assert.AreEqual(0, q.Count); q.Enqueue("a"); Assert.AreEqual(1, q.Count); q.Enqueue("b"); Assert.AreEqual(2, q.Count); q.Enqueue("c"); Assert.AreEqual(3, q.Count); Assert.IsTrue(q.Contains("a")); Assert.IsFalse(q.Contains("asdfawe")); var outval = q.Dequeue(); Assert.IsFalse(q.Contains("a")); } [TestMethod] public void SafeQueue_CantTellByDequeueIfQueueIsEmptyOrContainsNull() { var q = new SafeQueue(); Assert.IsNotNull(q); Assert.AreEqual(true, q.IsEmpty); q.Enqueue(null); Assert.AreEqual(false, q.IsEmpty); var result2 = q.Peek(); Assert.AreEqual(null, result2); Assert.AreEqual(false, q.IsEmpty); result2 = q.Dequeue(); Assert.AreEqual(true, q.IsEmpty); Assert.AreEqual(null, result2); } } 

你真正想要的是一个队列,你可以从你的数组创建一个队列,如下所示:

 var args = { "value1", "value2" }; var queue = new Queue(args); var arg1 = queue.Dequeue(); var arg2 = queue.Dequeue();