Validate the order of a List by custom strings I have a test where I have to validate the order of items in a List based on a pre-defined hierarchy that is being given to me as part of my assignment. Here it is below. 


Cat 
Dog 
Horse 
Elephant 


The items in the list would only ever be those four types, but the size of list is not limited. The list will be passed in as part of the method. There can be multiple of each or none at all. The below two list would be valid:


Cat 
Cat
Dog 
Elephant 


This would not.


Elephant 
Dog 
Horse 
Cat 


Below is what I have so far, and I feel as though there is a much more elegant solution. In particular, I would like to minimize the amount of bools and if statements I am using.

public bool ValidateAnimalOrder(List&lt;string&gt; listOfAnimals)
{
    bool catExists = false;
    bool dogExists = false;
    bool horseExists = false;
    bool elephantExists = false;

    for (int x = 0; x &lt; listOfAnimals.Count; x++)
    {
        if (listOfAnimals[x] == "Cat")
        {
            catExists = true;
            if(dogExists || horseExists || elephantExists)
            {
                return false;
            }
        }
        if (listOfAnimals[x] == "Dog")
        {
            dogExists = true;
            if (horseExists || elephantExists)
            {
                return false;
            }
        }
        if (listOfAnimals[x] == "Horse")
        {
            horseExists = true;
            if (elephantExists)
            {
                return false;
            }
        }
        if (listOfAnimals[x] == "Elephant")
        {
            elephantExists = true;
        }

    }

    return true;
}
Dictionary

I'd prefer to store animal names and their "values" in a dictionary.  

private static readonly Dictionary&lt;string, int&gt; AnimalValues = new Dictionary&lt;string, int&gt;
        {
            { "Cat", 1 },
            { "Dog", 2 },
            { "Horse", 3 },
            { "Elephant", 4 }
        };


Then the validation method will look like:

public static bool IsValidAnimalOrder(IEnumerable&lt;string&gt; animalNames)
{
    int prevValue = 0;
    foreach (string animalName in animalNames)
    {
        int curValue;
        if (!AnimalValues.TryGetValue(animalName, out curValue))
        {
            // If the animal's name is absent in the dictionary.
            return false;
        }
        if (curValue &lt; prevValue)
        {
            // If the current animal's value less than the previous one.
            return false;
        }
        prevValue = curValue;
    }
    return true;
}




switch

Alternative way is to use the switch operator instead of a dictionary as follows:

public static bool IsValidAnimalOrder(IEnumerable&lt;string&gt; animalNames)
{
    int prevValue = 0;
    foreach (string animalName in animalNames)
    {
        int curValue;
        switch (animalName)
        {
            case "Cat":
                curValue = 1;
                break;
            case "Dog":
                curValue = 2;
                break;
            case "Horse":
                curValue = 3;
                break;
            case "Elephant":
                curValue = 4;
                break;
            default:
                // If the animal's name is not listed above.
                return false;
        }
        if (curValue &lt; prevValue)
        {
            // If the current animal's value less than the previous.
            return false;
        }
        prevValue = curValue;
    }
    return true;
}




IEnumerable&lt;T&gt; problem

As @Mat's Mug♦ mentioned, IEnumerable&lt;T&gt; doesn't guarantee the order of its elements. So you could change argument type to IList&lt;T&gt; or IReadOnlyList&lt;T&gt;. But this will reject another enumerations with the specified order: IOrderedEnumerable&lt;T&gt; and IOrderedQueryable&lt;T&gt;.
As a workaround you could make the method above private and declare public overloads accepting all the suitable enumeration types above as argument:

public static bool IsValidAnimalOrder(IReadOnlyList&lt;string&gt; animalNames)
{
    return IsValidAnimalOrder((IEnumerable&lt;string&gt;)animalNames);
}

public static bool IsValidAnimalOrder(IOrderedEnumerable&lt;string&gt; animalNames)
{
    return IsValidAnimalOrder((IEnumerable&lt;string&gt;)animalNames);
}

public static bool IsValidAnimalOrder(IOrderedQueryable&lt;string&gt; animalNames)
{
    return IsValidAnimalOrder((IEnumerable&lt;string&gt;)animalNames);
}