检查子字符串键是否存在于word和返回值中

时间:2018-06-04 05:11:10

标签: c# data-structures

我正在努力寻找一种对会计软件的费用进行分类的最有效方法。值如下:

"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”。

我认为词典是解决这个问题的最快方法,但是对更好的方法提出建议。

提前致谢!

4 个答案:

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

我更喜欢干净且可扩展的代码,绝对不喜欢魔术字符串。