简体   繁体   中英

List.Any() with multiple conditions

I just wonder if it's possible to make it better (and I guess there are many, many better ways to do it). So the question is how to return true if in my list are 4 types of components. My list may contain 1000 of them , but I just need to return true if there are 4 objects of different types (CPU, GPU, RAM, PowerSupply). These objects are children of abstract class Component and contain property of enum type.

public bool IsWorking()
{
    bool hasCPU = AllComponents.Any(component => component.CompType == ComponentsType.CPU);
    bool hasGPU = AllComponents.Any(component => component.CompType == ComponentsType.GPU);
    bool hasPowerSupply = AllComponents.Any(component => component.CompType == ComponentsType.PowerSupply);
    bool hasRAM = AllComponents.Any(component => component.CompType == ComponentsType.RAM);
    bool? hasAllNeededComp // JUST WONDERING HOW TO MAKE IT BETTER
}

It depends on what you mean by "better". But if you want to make this as fast as possible, you should just use a foreach loop like this:

public bool IsWorking()
{
    bool hasCPU = false;
    bool hasGPU = false;
    bool hasPowerSupply = false;
    bool hasRAM = false;
    foreach(var component in AllComponents) 
    {
        if(component.CompType == ComponentsType.CPU) hasCPU = true;
        else if(component.CompType == ComponentsType.GPU) hasGPU = true;
        else if(component.CompType == ComponentsType.PowerSupply) hasPowerSupply = true;
        else if(component.CompType == ComponentsType.RAM) hasRAM = true;
        if(hasCPU && hasGPU && hasPowerSupply && hasRAM) return true;                   
    }
    return false;   
}

Not as fancy as some of these other solutions, but this will at most iterate through the list once.

Funny linq query :

new [] { ComponentsType.CPU, ComponentsType.GPU, ComponentsType.PowerSupply, ComponentsType.RAM }
    .Except(AllComponents.Select(component => component.CompType))
    .Any() == false;

You can group by CompType to get distinct ones, then add a where clause including all the needed components and count the result :

AllComponents.GroupBy(c => c.CompType)
             .Select(c => c.Key)
             .Where(c => c == ComponentsType.CPU
                         || c == ComponentsType.GPU
                         || c == ComponentsType.PowerSupply
                         || c == ComponentsType.RAM)
             .Count() == 4;

To be a bit cleaner, you can list the needed components and use Contains() :

var requirements = new List<ComponentsType>
{
    ComponentsType.CPU,
    ComponentsType.GPU,
    ComponentsType.PowerSupply,
    ComponentsType.RAM
};

return AllComponents.GroupBy(c => c.CompType)
                    .Select(c => c.Key)
                    .Where(c => requirements.Contains(c))
                    .Count() == 4;

I think it is readable:

public bool IsWorking()
{
    return AllComponents.Any(component => component.CompType == ComponentsType.CPU)
        && AllComponents.Any(component => component.CompType == ComponentsType.GPU)
        && AllComponents.Any(component => component.CompType == ComponentsType.PowerSupply)
        && AllComponents.Any(component => component.CompType == ComponentsType.RAM);
}

A more simpler code:

public bool IsWorking()
{
    ComponentsType[] requiredComps = new[] { ComponentsType.CPU, ComponentsType.GPU, ComponentsType.PowerSupply, ComponentsType.RAM };
    foreach (var requiredComp in requiredComps)
    {
        if (!AllComponents.Any(component => component.CompType == requiredComp))
            return false;
    }
    return true;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM