Search code examples
c#asp.netasp.net-mvcienumerable

Remove two or more itens form a list with predicate


I have a list that returns all status values except the exported one, however, I would like a list that returns all values except the exported and the authorized one (2 Status)

// Getting all status except the exported one
// GetStarusApontamento is a IEnumerable
var listStatus = this._apontamentoAppService.GetStatusApontamento().Where(x=>x != StatusApontamento.Exported).ToList();

How would I do something like that example:

var listStatus = this._apontamentoAppService.GetStatusApontamento().Where(x=>x != StatusApontamento.Exported && StatusApontamento.authorized).ToList();

There is also an condition that I remove a certain item from the list, for example, if the profile of the person is Admin

if (PerfildeAprovacao.PerfilDeValidacaoDeStatus.Equals("Administrador"))
{
    listStatus.RemoveAll(status => status != StatusApontamento.authorized);
}

Solution

  • Same way you do any other kind of Boolean test on two conditions. This is the computer logic "all shapes that are neither red nor blue":

    shape.Color != Red && shape.Color != Blue
    

    Or

    !(shape.Color == Color.Red || shape.Color == Color.Blue)
    

    Humans tend to struggle with the first form from a psychological viewpoint because they say "get me all the shapes that are not red or blue" (closer to the second form) rather than "get me all the shapes that aren't red and shapes that aren't blue"


    Even at two things, it's probably more readable to use a collection of the things you do/don't want:

    var want = new List<Color> { Color.Red, Color.Blue };
    shapes.Where(s => want.Contains(s.Color));
    
    var dontWant = List<Color> { Color.Red, Color.Blue };
    shapes.Where(s => !dontWant.Contains(s.Color));
    

    It's easier to extend to more this way, though I must say that I find it easier to read the "positive" want rather than the "double negative" dontwant form. It's probably also important to turn the logic in your mind so you're looking for "shapes where the list of colors I want contains the shape's color"

    Regarding treating admins differently, plenty of ways to do it, though strive for something readable. Perhaps:

    var adminsSee = new List<Color> { Color.Red, Color.Blue };
    shapes.Where(s =>
      (user.IsAdmin && adminsSee.Contains(s.Color)) || 
      (!user.IsAdmin && !adminsSee.Contains(s.Color))
    );
    

    This is "user is admin and color is in list of colors that admins see, or user is not admin and color is not in list of colors that only admins see"