我正在努力寻找一种对会计软件的费用进行分类的最有效方法。值如下:
"EFTPOS Kathmandu 2342342"
我创建了一个方法如下:
private static string Classifier(string inputDescription)
{
Dictionary<string, string> classified = new Dictionary<string, string>();
classified.Add("D/C FROM", "INCOME" );
classified.Add("CREDIT ATM", "INCOME");
classified.Add("INTEREST", "INCOME");
classified.Add("EFTPOS", "EXPENSE" );
classified.Add("DEBIT DEBIT", "EXPENSE");
classified.Add("CC DEBIT", "EXPENSE");
classified.Add("PAYMENT RECEIVED", "TRANSFER");
classified.Add("PAYMENT - THANK YOU", "TRANSFER");
classified.Add("IRD", "TAX" );
classified.Add("I.R.D", "TAX");
try
{
// What do I do here to get the value?
return value;
}
catch(Exception)
{
return "OTHER";
}
}
基本上,我想针对字典中的键运行inputDescription的值以获取其值(行项目的分类)。
因此,对于上面显示的示例,结果将是“EXPENSE”。
我认为词典是解决这个问题的最快方法,但是对更好的方法提出建议。
提前致谢!
答案 0 :(得分:1)
使用RegEx怎么样?
const string EXPENSE_PATTERN = "^(EFTPOS|DEBIT DEBIT|CC DEBIT)"
const string ..._PATTERN
if (Regex.IsMatch(input, EXPENSE_PATTERN)){
return "EXPENSE";
} else if (Regex.IsMatch(input, INCOME_PATTERN)){
return "INCOME";
} else if (Regex.IsMatch(input, ..._PATTERN)){
return "...";
} else {
return "OTHER"
}
答案 1 :(得分:0)
实现这一目标的方法之一是
string input = "EFTPOS Kathmandu 2342342";
string value = string.Empty;
foreach (var key in input.Split(' '))
{
value = classified.Where(k => classified.ContainsKey(k.Key)).Select(k => classified[k.Key]).FirstOrDefault();
if(value != null & value.trim()!= string.empty)
break;
}
检查value
是否为空以供进一步使用。 foreach循环将中断一次会找到值。
答案 2 :(得分:0)
通话方式:
static void Main(string[] args)
{
Console.WriteLine(Classifier("EFTPOS Kathmandu 2342342"));
Console.WriteLine(Classifier("D/C FROM Kathmandu 2342342"));
Console.ReadKey();
}
分类器方法:
private static string Classifier(string inputDescription)
{
var classified = new Dictionary<string, string>
{
{ "D/C FROM", "INCOME" },
{ "CREDIT ATM", "INCOME" },
{ "INTEREST", "INCOME" },
{ "EFTPOS", "EXPENSE" },
{ "DEBIT DEBIT", "EXPENSE" },
{ "CC DEBIT", "EXPENSE" },
{ "PAYMENT RECEIVED", "TRANSFER" },
{ "PAYMENT - THANK YOU", "TRANSFER" },
{ "IRD", "TAX" },
{ "I.R.D", "TAX" }
};
try
{
foreach (var kvp in classified)
if (inputDescription.StartsWith(kvp.Key))
return kvp.Value;
return "OTHER";
}
catch
{
return "OTHER";
}
}
返回:
EXPENSE
INCOME
当然,您可以将Dictionary定义移出方法之外,并使其成为类成员。如果您经常多次调用Classifier
,那将特别有意义。您还可以将其定义为IReadOnlyDictionary
,以防止更改其内容。
答案 3 :(得分:0)
从字典中获取内容的最简单方法是使用以下键:
Dictionary<string, string> classified = new Dictionary<string, string>();
var value = classified[key];
但当然你想要检查字典中的关键事件,如:
if(classified.ContainsKey(key))
return classified[key];
else
throw new InvalidTypeException();//this is because you should have all the key's mapped i.e you are only expecting known key types.People prefer other types like they would return null but i throw coz my dictionary is not having this key
现在来看价值观:
所有的值似乎都是已知的和重复的类型。所以我会建立一个枚举:
enum TransactionType
{
Expense,
Income,
Transfer
}
enum Source
{
EFTPOS,
DEBIT DEBIT,
...so on...
}
i prefer enums to avoid magic strings and people do make mistakes while typing strings.
所以现在使用Dictionary和enum的组合我将构建为:
private Dictionary<Source,TransactionType> PopulateSource()
{
Dictionary<Source,TransactionType> classified = new Dictionary<Source,TransactionType>();
//populate dictionary by iterating using
var keys = Enum.GetValues(typeof(Source));
var values = Enum.GetValues(typeof(TransactionType));
you can just iterate through keys if your keys and values in enum are in order .
return classified ;
}
public void TestSourceTransaction()
{
TransactionType transType;
var classifieds = PopulateSource();
var key = GetSourceType(inputDescription);//you need to write a method to get key from desc based on regex or string split options.
if(classifieds.ContainsKey(key))
classifieds[key].Value;
else
throw new InvalidTypeException("Source type undefined");
}
我更喜欢干净且可扩展的代码,绝对不喜欢魔术字符串。