2015-11-16 12 views
5

Powiedzmy mam obiektu MyCharacter klasy Character, który ma następujące właściwości: Health, Mana, MoveSpeed.
Z innej metody otrzymuję ciąg znaków, który zawiera następujące statystyki:
"Health: 100 Mana: 100 MoveSpeed: 100"
Teraz chcę przypisać te statystyki do mojego obiektu. Moja obecna próba jest następująca:wartości przypisać do obiektu w pętli for

// 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; 
    } 
} 

Chodzi o to, że znam kolejność statystyk. To zawsze Zdrowie, potem Mana, potem MoveSpeed. Tak więc szukam sposobu na uproszczenie go, a mianowicie pozbycie się tego switch (ponieważ rzeczywisty Character ma tutaj 18 statystyk i nie wygląda dokładnie tak dobrze, jak jest).
Mój pomysł będzie przebiegał przez tablicę i kazał programowi przypisać pierwszy znaleziony numer do Zdrowia, drugi do Many, a trzeci do MoveSpeed.
Czy coś takiego jest możliwe?

+2

Czy teraz masz żadnych obaw/performance/błąd na użyciu przełącznika przypadek? dlaczego chciałbyś zmienić? Jeśli nie, to wolałbym używać przełącznika, łatwiej jest debugować i czytać. – User2012384

+0

Jeśli znasz poprawną kolejność, dlaczego etykiety są na pierwszym miejscu? Czy istnieje powód, aby nie mieć np. '100,100,100'? – Luaan

+0

Jedynym sposobem, w jaki można dynamicznie wczytać się do właściwości bez znajomości ich nazw z góry, jest [użyj odbicia (wraz z odpowiednim wzrostem wydajności i zwiększeniem złożoności)] (http://stackoverflow.com/questions/771524/how -slow-is-reflection). TBH Nie widzę nic złego w tym, jak to jest teraz. [Każdy głupek może napisać kod, który komputer może zrozumieć. Dobrzy programiści piszą kod, który ludzie mogą zrozumieć] (http: // stackoverflow.com/questions/522828/is-code-for-computers-or-for-people) – Liam

Odpowiedz

7

Ponieważ wiesz, dokładny format, można po prostu przejść do indeksów bezpośrednio:

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

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

Można również użyć wyrażenia regularnego do tego, który ma tę zaletę, że dodatkowo sprawdza swój wzorzec (tak czy nie jest to przypadek, że robi nie dopasować format, pojawi się wyjątek):

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; 

Uwaga: prawdopodobnie chcesz te właściwości zawierają liczby całkowite, więc można obliczyć z wartości, więc należy zadzwonić int.Parse() dla każdej z wartości.

+0

Użyłem ostatniego dnia, aby dostać się do wyrażeń regularnych i cholera, to jest absolutnie idealne, dzięki, człowieku :) – Wilsu

0

Możesz po prostu wstawić spację lub dowolny znak jako separator pomiędzy wartościami. Jeśli zamówienie jest zawsze takie samo, nie będziesz mieć problemów. Jeśli czytasz ciąg z pliku, pisanie znaków jest bardziej nieefektywne niż zapisywanie danych w formacie binarnym jako nieprzetworzony plik złożony z elementów pływających. plik byłby sizeof (float) * 18. Wybierasz semantyczną wartość każdej wartości.

+0

Istnieje już separator ...? Czy przeczytałeś to pytanie? – poke

1

Możesz używać słownika. To będzie bardzo łatwe i proste.

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

następnie

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

W jaki sposób upraszcza to parsowanie? A jeśli już używasz innej struktury, dlaczego nie umieścić jej bezpośrednio w obiekcie znaku? – poke

+0

jak masz zamiar ustawić słownik. dodałeś wartości do siebie. nie z łańcucha, który jest problemem OP tutaj. –

+0

Dobrze, nie zauważyłem problemu z parsowaniem. –

0

Wyrażenia regularne to najlepszy sposób analizowania ciąg.

Sprawdź to:

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"); 
    } 
}