Как "удалить из списка" элемент из списка?
У меня есть список карт под названием _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 работает в "хвосте" или "в конце" списка.)
Если нет, как мне удалить первый элемент, но сохранить его в переменной?
Ответы
Ответ 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() ничего не возвращает.