5

Let's say I have an object MyCharacter of the class Character, which has the following properties: Health, Mana, MoveSpeed.
From a different method I get a string that contains these stats as follows:
"Health: 100 Mana: 100 MoveSpeed: 100"
I now want to assign these stats to my object. My current attempt is this:

// stats is the string I showed above
var statsArray = stats.Split(' ');
for (var i = 0; i < statsArray.Length; i++)
{
    switch(statsArray[i])
    {
        default:
            break;
        case "Health:":
            MyCharacter.Health = statsArray[i+1];
            break;
        case "Mana:":
            MyCharacter.Mana = statsArray[i+1];
            break;
        case "MoveSpeed:":
            MyCharacter.MoveSpeed = statsArray[i+1];
            break;
    }
}

The thing now is, that I know the order of the stats. It's always Health, then Mana, then MoveSpeed. So I am looking for a way to simplify it, namely getting rid of this switch (since the actual Character here has 18 stats and it's not exactly good looking as it is).
My idea would be going through the array and tell the program to assign the first number it finds to Health, the second to Mana and the third to MoveSpeed.
Is anything like that even possible?

6
  • 2
    Do you now have any concern / performance / error on using switch case? why you would like to change?? If not, to me, I would prefer using switch case, it's easier for debugging and reading Commented Nov 16, 2015 at 9:45
  • If you know the correct order, why have the labels in the first place? Is there a reason not to have e.g. 100,100,100? Commented Nov 16, 2015 at 9:49
  • The only way your going to be able to dynamically load into properties without knowing their names up front is to use reflection (with the associated performance hit and complexity increase). TBH I see nothing wrong with how it is now. Any fool can write code that a computer can understand. Good programmers write code that humans can understand Commented Nov 16, 2015 at 9:50
  • Another option if stats is a string is to use a string object notation, like Json, that way you can make your stringly typed object more explicit. Commented Nov 16, 2015 at 9:52
  • The main reason I'm looking for an alternative, besides maybe getting rid of the ~150 lines of code that I have right now, is learning purposes. It doesn't have anything to do with performance. Commented Nov 16, 2015 at 9:58

4 Answers 4

7

Since you know the exact format, you can just access the indexes directly:

string stats = "Health: 100 Mana: 100 MoveSpeed: 100";

var statsArray = stats.Split(' ');
MyCharacter.Health = statsArray[1];
MyCharacter.Mana = statsArray[3];
MyCharacter.MoveSpeed = statsArray[5];

You could also use a regular expression for this, which has the benefit that it further validates your pattern (so if there is a case that does not match your format, you get an exception):

var m = Regex.Match(stats, @"Health: (\d+) Mana: (\d+) MoveSpeed: (\d+)");

MyCharacter.Health = m.Groups[1].Value;
MyCharacter.Mana = m.Groups[2].Value;
MyCharacter.MoveSpeed = m.Groups[3].Value;

Note: You probably want those properties to contain integers so you can calculate with the values, so you should call int.Parse() on each of the values.

Sign up to request clarification or add additional context in comments.

1 Comment

I used the last day to get into regular expressions and damn, this is absolutely perfect, thanks, man :)
1

You can use dictionary. It will be very easy and simple.

Dictionary<string, int> dictionary =new Dictionary<string, int>();
dictionary.Add("health",100);
dictionary.Add("mana",100);
dictionary.Add("speed",40);

then

mycharacter.Health=dictionary["health"];
mycharacter.Health=dictionary["mana"];
mycharacter.Health=dictionary["speed"];

3 Comments

How does this simplify the string parsing? And if you already use another structure, why not put it in the character object directly?
how you are going to set up dictionary. you added values your self. not from the string which is the problem of OP here.
Right, I didn't notice parsing issue.
0

You can, just put a space, or any given character as a separator, in between the values. If the order is always the same you won't have problems. If you are reading the string from file, writing characters i fare more inefficient than writing the data in binary as a raw file composed by floats. the file would be sizeof(float)*18. You choose the semantic of each value.

Comments

0

Regular Expressions is the best way to parse the string.

Check this:

public class Character
{
    public int Health;
    public int Mana;
    public int MoveSpeed;

    public static Character FromString(string characterData)
    {
        MatchCollection matches = Regex.Matches(characterData, "[A-Za-z]+: ([\\d]+)");
        Character myCharacter = new Character();
        myCharacter.Health = Convert.ToInt32(matches[0].Groups[1].Value);
        myCharacter.Mana = Convert.ToInt32(matches[1].Groups[1].Value);
        myCharacter.MoveSpeed = Convert.ToInt32(matches[2].Groups[1].Value);
        return myCharacter;
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        Character myCharacter = Character.FromString("Health: 100 Mana: 110 MoveSpeed: 120");
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.