it-swarm.com.de

Feld in C # abbrechen

Ich habe ein String-Array in C # und ich möchte das oberste Element aus dem Array ziehen (dh das erste Element entfernen und alle anderen nach oben verschieben). Gibt es eine einfache Möglichkeit, dies in C # zu tun? Ich kann keine Array.Pop-Methode finden.

Muss ich so etwas wie eine ArrayList verwenden? Die Reihenfolge der Elemente in meinem Array ist wichtig.

21
robintw

Verwenden Sie stattdessen eine List , Queue oder Stack .

List<String>
Queue<String>
Stack<String>
31
driAn

Queue<T> (first in, first out) oder Stack<T> (last in, first out) sind das, wonach Sie suchen.

Arrays in .NET haben eine feste Länge - Sie können ein Element nicht aus ihnen entfernen oder ihnen Elemente hinzufügen. Sie können can mit einem List<T> tun, aber Queue<T> und Stack<T> sind geeigneter, wenn Sie eine Warteschlangen-/Stapelsemantik wünschen.

32
Jon Skeet

Von MSDN:

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class MSDNSample
    {
       static void Main()
       {
          string input = "a b c d";

          Stack<string> myStack = new Stack<string>(
             input.Split(new string[] { " " }, StringSplitOptions.None));

          // Remove the top element (will be d!)
          myStack.Pop();

          Queue<string> myQueue = new Queue<string>(

          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/

12
Paul Lefebvre

Da wir linq haben, ist das sehr einfach:

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

Dies ist in Array durchaus möglich, aber nicht effizient. Sie müssen Ihr Array mit einer Schleife nach unten verschieben und arr [i] = arr [i + 1] in einer for-Schleife einstellen. Danach müssen Sie, wenn Sie möchten, die Größe des Arrays ändern.

Aufgrund dieser Einschränkungen ist Array nicht die beste Datenstruktur, um Probleme zu lösen. Das Array eignet sich am besten für statische Daten oder für Daten, deren Größe sich nicht ändert.

Da Sie Daten entfernen möchten, ist das Array eindeutig nicht die Antwort. Insbesondere möchten Sie das erste/oberste Element aus Ihrer Auflistung platzieren, und es gibt bereits eine effiziente Datenstruktur, die dies ausführt: Stack .

Das ist die Schönheit von Datenstrukturen. Sie bieten Ihnen eine effiziente Möglichkeit, mit Ihren Sammlungen auf Basis Ihrer Anforderungen umzugehen.

1
harsimranb

Ich stieß auf die Besorgnis, die ich oben erwähnt hatte, hatte aber Probleme mit dem Standardverhalten von Queue, eine Ausnahme auszulösen, wenn die Sammlung leer war (nicht wirklich eine Ausnahmesituation). Dies ist meine Implementierung einer SafeQueue, die die meisten Operationen auf die Basisklasse zurückstellt, aber neue Dequeue()- und Peek()-Operationen implementiert, die default(T) zurückgeben, wenn die Warteschlange leer ist. In den Fällen, in denen default(T) zur Warteschlange hinzugefügt wurde (unwahrscheinlich für Objekttypen, aber sehr wahrscheinlich für Wertetypen), ist es unmöglich, nur mit Peek festzustellen, ob die Warteschlange leer ist. Eine neue IsEmpty-Eigenschaft macht es möglich, zu erkennen, wann Sie fertig sind.

public class SafeQueue<T>: Queue<T>
{
    public SafeQueue() : base() { }

    public SafeQueue(int count) : base(count) { }

    public SafeQueue(IEnumerable<T> 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<string>(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<string>();
        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<string>();
        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<string>();
        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<string>(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<string>();
        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);
    }

}
1

Ich stimme dem zu, aber ich habe eine kleine Verbesserung. 

  public static class ArrayExtensions
    {
        /// <summary>
        /// Removes the last element.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="array">The array.</param>
        /// <returns>T[].</returns>
        public static T[] RemoveLastElement<T>(this T[] array)
        {
            var stack = new Stack<T>(array);
            stack.Pop();
            return stack.ToArray().Reverse().ToArray();
        }

        /// <summary>
        /// Removes the first element.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="array">The array.</param>
        /// <returns>T[].</returns>
        public static T[] RemoveFirstElement<T>(this T[] array)
        {
            var queue = new Queue<T>(array);
            queue.Dequeue();
            return queue.ToArray();
        }
    }

Und um es komplett zu machen, hier ist der Test:

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

Was Sie eigentlich wollen, wird Warteschlange genannt. Sie können eine Warteschlange aus Ihrem Array erstellen.

var args = { "value1", "value2" };
var queue = new Queue<string>(args);
var arg1 = queue.Dequeue();
var arg2 = queue.Dequeue();
0
Pellet

Der Vollständigkeit halber ist dies auch schnell;

    /// <summary>
    /// Pop value from top of string[] array
    /// </summary>
    public void PopStringArray(ref string[] array)
    {
        int newLength = array.Length;
        string[] temp = new string[array.Length];

        for (int i = array.Length - 1; i >= 1; i--)
            temp[i - 1] = array[i];

        array = temp;
    }
0
Markus Hooge