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

Как "удалить из списка" элемент из списка?

У меня есть список карт под названием _deck:

 private List<String> _deck = new List<String> {"2h", "3h", "4h", ... }

А потом я хочу удалить карту из списка и сохранить в переменную. Я пытаюсь сделать:

 String p1FirstCard = _deck.RemoveAt(0);

но я получаю сообщение об ошибке "Невозможно преобразовать тип void в String".

В списке С# есть что-то вроде push/pop, но что делает это в "head" или "start" List? (Push/pop работает в "хвосте" или "в конце" списка.)

Если нет, как мне удалить первый элемент, но сохранить его в переменной?

4b9b3361

Ответ 1

Вы можете сделать это в два этапа:

String p1FirstCard = _deck[0];
_deck.RemoveAt(0);

Вы можете написать свой собственный вспомогательный метод расширения (я добавил индекс в Pop, так как @Fredou предложил:

static class ListExtension
{
    public static T PopAt<T>(this List<T> list, int index)
    {
        T r = list[index];
        list.RemoveAt(index);
        return r;
    }
}

а затем вызовите

String p1FirstCard = _deck.PopAt(0);

P.S. Имя может быть немного запутанным. Pop обычно удаляет последний элемент, а не первый.

Ответ 2

Вы могли бы просто использовать класс Queue, который уже есть в С#?

class Program
{
    static void Main(string[] args)
    {
        var _deck = new Queue<String>();
        _deck.Enqueue("2h");
        _deck.Enqueue("3h");
        _deck.Enqueue("4h");
        _deck.Enqueue("...");

        var first = _deck.Dequeue(); // 2h
        first = _deck.Dequeue(); // 3h
    }
}

или вы могли бы просто использовать класс Stack, который уже есть в С#?

class Program
{
    static void Main(string[] args)
    {
        var _deck = new Stack<String>();
        _deck.Push("2h");
        _deck.Push("3h");
        _deck.Push("4h");
        _deck.Push("...");

        var first = _deck.Pop(); // ...
        first = _deck.Pop(); // 4h
    }
}

Ответ 3

Если вам нужен прямой эквивалент pop(), вам придется написать свой собственный, потому что я не думаю, что что-либо на С# автоматически имеет "Удалить из конца и возврата". Однако есть Queue (сначала сначала, так и первый) и Stack (первый в, последний выход) вместо простого List.

Также существует класс LinkedList, который позволяет добавлять или удалять как из начала, так и из конца, но предоставленный RemoveFirst() и RemoveLast() не автоматически возвращают удаляемый элемент - для этого вам нужно написать метод расширения, например, AlexD.

Все это касается удаления вещей с самого начала или конца списка. Если вы просто хотите удалить произвольный элемент из середины List, всегда будет List.Remove(item), который удаляет определенный элемент из списка (а не по положению).

Ответ 4

На основе ответа AlexD я добавил еще несколько методов расширения:

public static class ListExtensionMethods
{
    public static T PopAt<T>(this List<T> list, int index)
    {
        var r = list[index];
        list.RemoveAt(index);
        return r;
    }

    public static T PopFirst<T>(this List<T> list, Predicate<T> predicate)
    {
        var index = list.FindIndex(predicate);
        var r = list[index];
        list.RemoveAt(index);
        return r;
    }

    public static T PopFirstOrDefault<T>(this List<T> list, Predicate<T> predicate) where T : class
    {
        var index = list.FindIndex(predicate);
        if (index > -1)
        {
            var r = list[index];
            list.RemoveAt(index);
            return r;
        }
        return null;
    }
}

Ответ 5

 private List<String> _deck = new List<String> {"2h", "3h", "4h", ... }
 //Save into variable first
 String p1FirstCard = _deck[0];
 //Now just remove it
 _deck.RemoveAt(0);

RemoveAt() ничего не возвращает.