Como remover o item da lista em c #?

189

Eu tenho uma lista armazenada na lista de resultados da seguinte maneira:

var resultlist = results.ToList();

Parece algo assim:

ID FirstName  LastName
-- ---------  --------
1  Bill       Smith
2  John       Wilson
3  Doug       Berg

Como removo o ID 2 da lista?

Nate Pet
fonte

Respostas:

364

List<T> possui dois métodos que você pode usar.

RemoveAt (int index) pode ser usado se você souber o índice do item. Por exemplo:

resultlist.RemoveAt(1);

Ou você pode usar Remover (item T) :

var itemToRemove = resultlist.Single(r => r.Id == 2);
resultList.Remove(itemToRemove);

Quando você não tiver certeza de que o item realmente existe, poderá usar o SingleOrDefault . SingleOrDefaultretornará nullse não houver nenhum item ( Singlelançará uma exceção quando não conseguir encontrar o item). Ambos serão lançados quando houver um valor duplicado (dois itens com o mesmo id).

var itemToRemove = resultlist.SingleOrDefault(r => r.Id == 2);
if (itemToRemove != null)
    resultList.Remove(itemToRemove);
Wouter de Kort
fonte
5
bem, do que talvezvar itemsToRemove = resultlist.Where(r => r.Id == 2); foreach (var itemToRemove in ItemsToRemove) resultList.Remove(itemToRemove);
Vlad
1
Isso não deveria ser resultlist.Items.RemoveAt(1);?
DreamTeK
48

Resposta curta:
Remover (da lista results)

results.RemoveAll(r => r.ID == 2);irá remover o item com ID 2 em results(no local).

Filtro (sem remover da lista original results):

var filtered = result.Where(f => f.ID != 2);retorna todos os itens, exceto aquele com ID 2

Resposta detalhada:

Eu acho que .RemoveAll()é muito flexível, porque você pode ter uma lista de IDs de itens que deseja remover - considere o exemplo a seguir.

Se você tem:

class myClass {
    public int ID; public string FirstName; public string LastName;
}

e atribuiu alguns valores da resultsseguinte maneira:

var results=new List<myClass> {
    new myClass()  { ID=1, FirstName="Bill", LastName="Smith" },
    new myClass()  { ID=2, FirstName="John", LastName="Wilson" },
    new myClass()  { ID=3, FirstName="Doug", LastName="Berg" },
    new myClass()  { ID=4, FirstName="Bill", LastName="Wilson" },
};

Em seguida, você pode definir uma lista de IDs para remover:

var removeList = new List<int>() { 2, 3 };

E simplesmente use isso para removê-los:

results.RemoveAll(r => removeList.Any(a => a==r.ID));

Ele removerá os itens 2 e 3 e manterá os itens 1 e 4 - conforme especificado pelo removeList. Observe que isso acontece no local, portanto, não há atribuição adicional necessária.

Obviamente, você também pode usá-lo em itens únicos como:

results.RemoveAll(r => r.ID==4);

onde ele removerá o projeto de lei com o ID 4 em nosso exemplo.


DotNetFiddle: Execute a demonstração

Matt
fonte
45
resultList = results.Where(x=>x.Id != 2).ToList();

Gosto de um pouco de ajuda do Linq que é fácil de implementar e pode fazer consultas com condições "onde não" um pouco mais fáceis de ler:

public static IEnumerable<T> ExceptWhere<T>(this IEnumerable<T> source, Predicate<T> predicate)
{
    return source.Where(x=>!predicate(x));
}

//usage in above situation
resultList = results.ExceptWhere(x=>x.Id == 2).ToList();
KeithS
fonte
1
Outra abordagem semelhante (que usa um predicado) é usar List.FindIndex/ List.RemoteAt(que possui o recurso "bom" ou "não tão bom" de ser uma operação de mutação).
É verdade, mas tenha cuidado ao dizer que a operação da List está mudando. Lista usa uma matriz nos bastidores e pode recriar sua matriz com uma capacidade menor ou maior quando achar necessário. Normalmente , a remoção é uma mutação no local da matriz existente.
Keith
Este segmento seguro não é, e por sua simplicidade você pode apenas usar SingleOrDefault, ele does not necessidade de ser contido em um método estático
Ninguém disse que era seguro para threads (e se depende do que os threads deveriam estar fazendo; pode ser preferível fornecer uma construção de memória diferente para um thread de trabalho, em vez de permitir que todos trabalhem em uma coleção simultânea ) e o OP deseja todos os registros, exceto o correspondente ao predicado, para que SingleOrDefault retorne exatamente o que eles não desejam. O "método estático" é de fato um método de extensão, como a maioria do Linq, e funciona sempre que o que você não deseja (um elemento ou muitos) é mais fácil de definir do que o que você faz.
Keiths
5

Existe outra abordagem. Ele usa List.FindIndexe List.RemoveAt.

Embora eu provavelmente usasse a solução apresentada pelo KeithS (apenas o simples Where/ ToList), essa abordagem difere porque muda o objeto da lista original. Isso pode ser um "recurso" bom (ou ruim), dependendo das expectativas.

Em qualquer caso, o FindIndex(acoplado a uma proteção) garante que a RemoveAtcorreção estará correta se houver lacunas nos IDs ou se a ordem estiver errada etc., e o uso de RemoveAt(vs Remove) evita uma segunda pesquisa de O (n) na lista.

Aqui está um trecho de LINQPad :

var list = new List<int> { 1, 3, 2 };
var index = list.FindIndex(i => i == 2); // like Where/Single
if (index >= 0) {   // ensure item found
    list.RemoveAt(index);
}
list.Dump();        // results -> 1, 3

Feliz codificação.


fonte
4

Você não especifica que tipo de lista, mas a Lista genérica pode usar o RemoveAt(index)método ou o Remove(obj)método:

// Remove(obj)
var item = resultList.Single(x => x.Id == 2);
resultList.Remove(item);

// RemoveAt(index)
resultList.RemoveAt(1);
mgnoonan
fonte
4

Mais simplificado:

resultList.Remove(resultList.Single(x => x.Id == 2));

não há necessidade de criar um novo objeto var.

Javier Andres Caicedo
fonte
0

... ou apenas resultlist.RemoveAt(1)se você souber exatamente o índice.

Vlad
fonte
0
{
    class Program
    {
        public static List<Product> list;
        static void Main(string[] args)
        {

            list = new List<Product>() { new Product() { ProductId=1, Name="Nike 12N0",Brand="Nike",Price=12000,Quantity=50},
                 new Product() { ProductId =2, Name = "Puma 560K", Brand = "Puma", Price = 120000, Quantity = 55 },
                 new Product() { ProductId=3, Name="WoodLand V2",Brand="WoodLand",Price=21020,Quantity=25},
                 new Product() { ProductId=4, Name="Adidas S52",Brand="Adidas",Price=20000,Quantity=35},
                 new Product() { ProductId=5, Name="Rebook SPEED2O",Brand="Rebook",Price=1200,Quantity=15}};


            Console.WriteLine("Enter ProductID to remove");
            int uno = Convert.ToInt32(Console.ReadLine());
            var itemToRemove = list.Find(r => r.ProductId == uno);
            if (itemToRemove != null)
                list.Remove(itemToRemove);
            Console.WriteLine($"{itemToRemove.ProductId}{itemToRemove.Name}{itemToRemove.Brand}{itemToRemove.Price}{ itemToRemove.Quantity}");
            Console.WriteLine("------------sucessfully Removed---------------");

            var query2 = from x in list select x;
            foreach (var item in query2)
            {
                /*Console.WriteLine(item.ProductId+" "+item.Name+" "+item.Brand+" "+item.Price+" "+item.Quantity );*/
                Console.WriteLine($"{item.ProductId}{item.Name}{item.Brand}{item.Price}{ item.Quantity}");
            }

        }

    }
}
Prabhakaran M
fonte