Gaff
Gaff

Reputation: 5667

Good way to do a string lookup based on multiple scores in C# or Java

I am looking for a good way to return a string based on various scores in either C# or Java. For example, let's say I have the following scores represented by doubles:

double scoreIQ = 4.0;
double scoreStrength 2.0;
double scorePatience 9.0;

Let's say I wanted to return a string based on the above scores. What would be a good way to structure this in a clear, easy to understand way unlike the following:

public static string ReturnScore(double scoreIQ, double scoreStrength, double scorePatience)
    {

        if (scoreIQ <= 5.0)
        {
            if (scoreStrength <= 5.0)
            {
                if (scorePatience <= 5.0)
                {
                    return "You're stupid, weak, and have no patience";

                }
                else if (scorePatience <= 7.5)
                {
                    return "You're stupid, weak, and have some patience";
                }
                else
                {
                    return "You're stupid, weak, and have a lot of patience";
                }
            }
            //Continue elseif return string permutations here
        }
        //Continue elseif return string permutations here
    }

Things that immediately come to mind would be to remove the hard-coded strings and use a string creator of keywords/phrases that creates sentences based on the scores. I don't want to use nested if-statements because what if I wanted to go beyond 3 scores? The permutations are going to increase exponentially.

The above is just an example and what I am looking for is some structure that can handle such a scenario. Clearly, this is the wrong way of doing it. I am looking for someone to guide me in the right direction. Thanks!

Upvotes: 4

Views: 151

Answers (3)

deepee1
deepee1

Reputation: 13196

Using a dictionary you could do something like this...

class Program
{
    static void Main(string[] args)
    {
        ScoreTextTranslator dec = new ScoreTextTranslator();
        dec.IfAtLeast(0, "stupid");
        dec.IfAtLeast(5, "average intelligence");
        dec.IfAtLeast(6, "smart");
        Console.WriteLine(dec.GetTextForScore(5.7f));
    }
}

class ScoreTextTranslator
{
    Dictionary<float, string> backing = new Dictionary<float, string>();
    public void IfAtLeast(float value, string text)
    {
        backing.Add(value, text);
    }
    public string GetTextForScore(float ActualScore)
    {
        var scoreRange = backing.Keys.Where(a => a <= ActualScore);
        if (scoreRange.Count() == 0)
            throw new Exception("No valid score text exists");
        else
            return backing[scoreRange.Max()];
    }
}

Upvotes: 1

Walter Laan
Walter Laan

Reputation: 2976

In Java you could use a NavigableMap (no idea of there is something similar in C#)

TreeMap<Double, String> patience = new TreeMap<Double, String>();
patience.put(0.0, "no");
patience.put(5.0, "some");
patience.put(7.5, "a lot of");

System.out.println("You have " + patience.floorEntry(6.0).getValue() + " patience!");

See http://docs.oracle.com/javase/7/docs/api/java/util/NavigableMap.html

Upvotes: 2

dcp
dcp

Reputation: 55449

If you have a series of yes no values, one way would be a bitmask, where each bit represents one of the yes no values.

For example, let bit 0 (bits numbered from right to left, starting at 0) be true for scoreIQ >= 4.0, and 0 otherwise.

Let bit 1 be true for scoreStrength >= 2.0, and 0 otherwise.

Let bit 2 be true for scorePatience >= 9.0, and 0 otherwise.

So, if you wanted to know if someone has a high IQ and is very patient, but is not strong, you could use the AND operator with a bitmask of 101 to perform this test.

Other examples:

000 - person has poor IQ, is not strong, and is not patient
001 - person has good IQ, is not strong, and is not patient
011 - person has good IQ, is strong, and is not patient
110 - person has poor IQ, is strong, and is patient

As new criteria are added, you just use a another bit for the new criteria.

So, to build a bitmask to test the characteristics you care about, you can just do something like this:

// find out if person has good IQ and is patient, but not strong
int mask = 0;
mask |= (1<<0);  // set bit 0 (good IQ)
mask |= (1<<2);  // set bit 2 (patient)
if (personsMask & mask == mask) {
    // you know the person has a good IQ and is patient, but they are `not` strong
}

Upvotes: 2

Related Questions