Remove an item from a List

5

Well, I have a method that I query on my bank and compare with a List<Carros> . My intention is, for each item that contains both in my query, and in my List<Carros> , I remove the item from my List<Carros> .

 private List<Carros> GetCarros(long userId, List<Carros> list)
 {
     var retornaCarros = _CarrosRepository.GetCarrosType(CarrosType.ROSA.Value, userId);

     if (retornaCarros.Count() > 0)
     {
         foreach (var itemCarros in retornaCarros)
         {
            // AQUI REMOVER O ITEM QUE TENHA NO MEU LIST<>
         }
     }

     return new List<Carros>();
 }
    
asked by anonymous 08.05.2015 / 16:33

2 answers

6

You can use the Except method. ( System.Linq ) to resolve the problem:

private IEnumerable<Carros> GetCarros(long userId, List<Carros> list)
{
    var retornaCarros = _CarrosRepository.GetCarrosType(CarrosType.ROSA.Value, userId);
    return list.Except(retornaCarros);
}

The Except method returns a list with elements of the first list (in this case, list ) that do not appear in the second list ( retornaCarros ).

(If you want to return List<Carros> instead of IEnumerable<Carros> call method .ToList() (return list.Except(retornaCarros).ToList() ) and change the method signature.

(See an example in DotNetFiddle.)

EDIT (Relatively to Dcastro's comment):

In fact, in the case of its class Carros it is necessary that this knife override methods .GetHashCode() and .Equals(object obj) so that .Except() is successful.

However, it is not always possible to do these overrides . So, one way to solve the problem is to create a class that implements IEqualityComparer<Carros> . An instance of this class can be passed to .Except() , which in turn will use it to make the comparison (instead of using the methods of the base class object ).

A possible implementation (assuming there is a UniqueId property in the Carros class):

public class CarrosComparer: IEqualityComparer<Carros>
{
    public int GetHashCode(Carros carro)
    {
        return carro.UniqueId;
    }

    public bool Equals(Carros carro1, Carros carro2)
    {
        return carro1.UniqueId == carro2.UniqueId;
    }
}

Then you can do the following:

private IEnumerable<Carros> GetCarros(long userId, List<Carros> list)
{
    var retornaCarros = _CarrosRepository.GetCarrosType(CarrosType.ROSA.Value, userId);
    return list.Except(retornaCarros, new CarrosComparer());
}

(See an example in DotNetFiddle.)

An interesting note about how IEqualityComparer is used:

The .Equals() method is only invoked if the hash codes of both instances are equal. You can check this by changing .GetHashCode() in fiddle above.

    
08.05.2015 / 16:45
4

Use the Remove method of class List<T>

private List<Carros> GetCarros(long userId, List<Carros> list)
{
    var retornaCarros = _CarrosRepository.GetCarrosType(CarrosType.ROSA.Value, userId);

    // Como muito bem disse o Omni o if não é necessário
    //if (retornaCarros .Count() > 0)
    //{
        foreach (var itemCarros in retornaCarros )
        {
           list.Remove(itemCarros);
        }
    //}

    return list;
}

Note: Beginning child retornaCarros is of type List<Carros> .

EDIT

As the dcastro commented on the Omni response, also the Remove method to work correctly on reference types , they will have to implement the interface IEquatable .

Assuming that Carros is an entity it will have an ID field, so it is easy to implement the interface:

public class Carros : IEquatable<Carros>
{

    //Suas Propriedades
    //Seus Métodos

    public override bool Equals(object obj)
    {
        if (obj == null) return false;
        Carros objAsCarros = obj as Carros;
        if (objAsCarros == null) return false;
        else return Equals(objAsCarros);
    }

    public override int GetHashCode()
    {
        return ID;
    }

    public bool Equals(Carros other)
    {
        if(other == null)return false;
        return ID.Equals(other.ID);
    }
}

Note: You should replace ID with the name of the Carros property that makes it unique.

    
08.05.2015 / 16:39