Подтвердить что ты не робот

Сбросить массив в С#

У меня есть строковый массив в С#, и я хочу вытащить верхний элемент из массива (т.е. удалить первый элемент и перенести все остальные на один). Есть ли простой способ сделать это на С#? Я не могу найти метод Array.Pop.

Мне нужно использовать что-то вроде ArrayList? Порядок элементов в моем массиве важен.

4b9b3361

Ответ 2

Queue<T> (сначала в первом порядке) или Stack<T> (последний раз, первый раз) - это то, что вам нужно.

Массивы в .NET фиксированной длины - вы не можете удалить элемент из них или действительно добавить к ним элементы. Вы можете сделать это с помощью List<T>, но Queue<T> и Stack<T> более подходят, если вам нужна семантика очереди/стека.

Ответ 3

Из 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/

Ответ 4

Так как мы имеем linq:

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

Ответ 5

Я столкнулся с проблемой, о которой упомянул выше, но у меня были проблемы с поведением очереди по умолчанию, создавая исключение, когда коллекция была пустой (на самом деле это не исключительная ситуация). Это моя реализация SafeQueue, которая откладывает большинство операций до базового класса, но реализует новые Dequeue() и Peek() которые возвращают default(T) если очередь пуста. В тех случаях, когда это возможно, по default(T) было добавлено в очередь (маловероятно для типов объектов, но очень вероятно для типов значений), невозможно определить, является ли очередь пустой только с помощью функции Peek. Новое свойство IsEmpty позволяет узнать, когда вы закончите.

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

}

Ответ 6

Это вполне возможно в массиве, но оно неэффективно. Вам буквально приходится перемещать ваш массив с помощью цикла и установки arr [i] = arr [i + 1] в цикле for. После этого, если хотите, вы должны изменить размер массива.

Из-за этих оговорок массив не лучшая структура данных для решения проблемы. Массив лучше всего для статических данных или данных, размер которых не изменится.

Поскольку вы хотите удалить данные, массив явно не является ответом. В частности, вы хотите вывести первый/верхний элемент из вашей коллекции, и уже есть эффективная структура данных, которая делает это: Stack.

Это красота структур данных, они дают вам эффективный способ обработки ваших коллекций на основе ваших требований.

Ответ 7

Я согласен с вышеизложенным, но у меня есть небольшое улучшение.

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

И чтобы сделать это, вот тест:

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

Ответ 8

То, что вы на самом деле хотите, называется Queue, вы можете создать очередь из своего массива следующим образом:

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

Ответ 9

Для полноты, это также быстро;

    /// <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;
    }