Убедитесь, что ключ подстроки существует в слове и возвращаемом значении - PullRequest
0 голосов
/ 04 июня 2018

Я пытаюсь найти наиболее эффективный по времени способ классификации расходов на часть бухгалтерского программного обеспечения.Значения приходят следующим образом:

"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 для ключей всловарь, чтобы получить его значение (классификация позиции).

Так что для примера, показанного выше, результатом будет "РАСХОД".

Я предполагал, что словарь будет самым быстрым способомподходите к этому, но открыты для предложений по лучшим методам.

Заранее спасибо!

Ответы [ 4 ]

0 голосов
/ 04 июня 2018

Самый простой способ получить что-то из словаря - использовать ключ, например:

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.

То же самое с комбинацией словаря и перечислениятеперь я бы построил как:

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

Я предпочитаю чистый и расширяемый код и абсолютное нет магической строке.

0 голосов
/ 04 июня 2018

А как насчет использования 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"
}
0 голосов
/ 04 июня 2018

Метод вызова:

    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

Конечно, вы можете переместить определение словаря за пределы методаи сделать его членом класса.Это особенно важно, если у вас есть несколько частых звонков на Classifier.Вы также можете определить его как IReadOnlyDictionary, чтобы предотвратить изменение его содержимого.

0 голосов
/ 04 июня 2018

Один из способов добиться этого -

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 оборвется, как только найдет значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...