我正在开发一个小帮手应用程序,并想知道是否有更好的方法来完成这一件事 -
我有一个CSV文件,我正在读取我的程序,我正在解析每行中的一个值,从一个数值(总是一个整数,在1到5之间)到一个字符串值,以便在程序中更容易表示。当我保存文件时,我需要从字符串表示转换回数字表示。目前,我通过switch语句执行此操作,但我知道必须有一种更简洁的方法来实现此目的。
我目前使用的函数有两个参数。其中一个参数是一个字符串,可以是我试图解析的那个值的数字表示或字符串表示,另一个值是一个布尔值,告诉函数它应该转换第一个参数的方式。如果boolean参数为true,则转换为数字表示形式,如果为false,则转换为字符串表示形式。这是我解析值的函数:
string ParseRarity(string rarity, bool toNumericalStr)
{
if (toNumericalStr)
{
switch (rarity)
{
case "Very Common":
return "1";
case "Common":
return "2";
case "Standard":
return "3";
case "Rare":
return "4";
case "Very Rare":
return "5";
}
}
else
{
switch (rarity)
{
case "1":
return "Very Common";
case "2":
return "Common";
case "3":
return "Standard";
case "4":
return "Rare";
case "5":
return "Very Rare";
}
}
return "";
}
任何缩短此代码的帮助将不胜感激,所以“谢谢”提前!
我也会给你一个答案,你可以创建一个包含稀有值的静态“存储库”类。下划线存储机制是Dictionary<int, string>
。这将强制你所有的稀有物具有一个唯一的密钥(int
),并且通过该密钥可以快速访问。
public static class RarityRepository
{
private static Dictionary<int, string> _values = new Dictionary<int, string>()
{
{ 1, "Very Common" },
{ 2, "Common" },
{ 3, "Standard" },
{ 4, "Rare" },
{ 5, "Very Rare" },
};
public static string GetStringValue(int input)
{
string output = string.Empty; // returns empty string if no matches are found
_values.TryGetValue(input, out output);
return output;
}
public static int GetIntValue(string input)
{
var result = _values.FirstOrDefault(x => string.Compare(x.Value, input, true) == 0);
if (result.Equals(default(KeyValuePair<int,string>)))
{
return -1; // returns -1 if no matches are found
}
return result.Key;
}
}
我做了一个小提琴here,感谢@Ron寻找我的午夜脑代码缺陷!
如果你想简单的污垢,只需编写一个像这样的静态助手类:
public class CodeConverter
{
private static readonly string[] lookup = new []
{
"[Unknown]",
"Very Common",
"Common",
"Standard",
"Rare",
"Very Rare"
};
public static string CodeToString(int code)
{
if (code < 0 || code > lookup.GetUpperBound(0)) code = 0;
return lookup[code];
}
public static int StringToCode(string text)
{
int i = Array.IndexOf(lookup, text);
return Math.Min(0,i);
}
}
你可以做一些非常简单的事情,但你应该把它分成两种方法。有一种做两件事的方法是非常糟糕的架构。
public static class RarityConverter
{
private static List<Tuple<int, string>> Rarities = new List<Tuple<int, string>>()
{
new Tuple<int, string>(1, "Very Common"),
new Tuple<int, string>(2, "Common"),
new Tuple<int, string>(3, "Standard"),
new Tuple<int, string>(4, "Rare"),
new Tuple<int, string>(5, "Very Rare"),
};
public static string ToString(int rarity)
{
return Rarities.FirstOrDefault(t => t.Item1 == rarity)?.Item2;
}
public static int? ToInt(string rarity)
{
return Rarities.FirstOrDefault(t => string.Compare(t.Item2, rarity, true) == 0)?.Item1;
}
}
您也可以使用Enum,但这需要您使用DescriptionAttribute
来装饰/转换传入的字符串名称到枚举名称。
我将创建一个可以存储两个值的类,然后根据需要调用每个值。
public class Rarity
{
public Rarity(int numValue)
{
NumValue = numValue;
switch(numValue)
{
case 1:
StringValue = "Very Common";
break;
case 2:
StringValue = "Common";
break;
case 3:
StringValue = "Standard";
break;
case 4:
StringValue = "Rare";
break;
case 5:
StringValue = "Very Rare";
break;
default:
StringValue = "";
break;
}
}
public int NumValue { get; }
public string StringValue { get; }
}
在加载CSV值时,可以使用您提到的int值初始化类对象(在我的示例中为Rarity)。
Rarity rarity = new Rarity(my_csv_int_value);
现在,您可以随时获取所需的价值。
rarity.NumValue //1,2,3,4,5
rarity.StringValue //Very Common, Common, etc...
可能大约相同数量的代码,但更通用,你不必继续解析字符串。
我建议
enum,即使有额外的装饰需求。对我来说唯一的另一个竞争力是数据应该存在于数据域中,而不是代码域中,所以我很可能在代码中没有明确地显示这些值!
我不推荐这种确切的方法或OP的方法,我回答了简洁的需要
你的逻辑已经在字符串到字符串转换的土地上。为什么不O(1)双向查找?你可以有一个双向查找/字典。
var lookup = new Dictionary<string, string>()
{
{ ”1”, "Very Common" },
{ “2”, "Common" },
{ “3”, "Standard" },
{ “4,” "Rare" },
{ “5”, "Very Rare" },
{ “Very Common”, “1” }
//etc iPhone editing sucks
};
您甚至可以只写出Dictionary的正向查找一半,并在反向查找部分中使用扩展方法或专用类ToTwoWayLookup填充,而不必键入2x值。 (有关方法,请参阅how to do a dictionary reverse lookup的接受答案),您也可以删除ContainsKey检查
然后在你的函数中你摆脱了bool参数,只是在这个字典中查找。我不知道函数名是什么... FlipRepresentation?
我可能会这样做
也许单独使用reverseLookup字典会更有意义,因此您可以使用两个具有更有意义名称的方法。 Terseness并非全部!努力使代码可以被其他人理解!我更喜欢读ToNumerical(“Common”),ToNumberFromRarityName,ToRarityName(“1”)或ToRarityNameFromNumber而不是FlipRepresentation('1“)或ParseRarity(”1“,false);
我可能不会留下字符串< - >字符串为字符串< - > int land,就像其他建议在从文件读取时保存对int.Parse(val)的调用。
这似乎是这个值的标准,如果是我,我会简化这个(根据要求,我会添加范围检查或错误处理)。
public static class Rarities
{
private static List<string> _rarityValues = new List<string>()
{
"Empty",
"Very Common",
"Common",
"Standard",
"Rare",
"Very Rare"
};
public static string ToRarityString(this int rarity)
{
return _rarityValues[rarity];
}
public static int ToRairityInt(this string rarity)
{
return _rarityValues.IndexOf(rarity);
}
}
然后你可以直接从值调用:
var rarityInt = 1;
var rarityString = "Rare";
var stringValue = rarityInt.ToRarityString();
var intValue = rarityString.ToRairityInt();