Рассчитать разницу по алфавитной шкале оценок - PullRequest
1 голос
/ 02 августа 2020

У меня есть такая оценочная алфавитная шкала:

введите описание изображения здесь

У меня System.Data.DataTable в столбце Current risk есть одно из это возможные значения и в столбце Forward risk снова одно из этих значений, и мне нужно вычислить разницу между текущим и форвардным риском и поместить этот результат в другой столбец. Разница рассчитывается таким образом: Примеры:

Если Current = AAA и Forward = AA + -> Разница = -1

Если Current = AAA и Forward = AAA -> Разница = 0

Если Текущий = AAA и вперед = AA -> разница = -2

если текущий = AAA и вперед = AA- -> разница = -3

если ток = AA + и вперед = AAA -> Разница = + 1

Если Current = AA и Forward = AAA -> Difference = + 2

Если Current = A и Forward = AAA -> Difference = + 5

Я использую структуру C#. net, и единственное решение, которое я имею в виду, - это тонны if-then, но я хотел бы знать, есть ли лучшее и элегантное решение для этой проблемы. Спасибо

Ответы [ 3 ]

1 голос
/ 04 августа 2020

Если вы создаете Dictionary для сопоставления строк риска с целыми числами, вы можете просто обрабатывать каждую строку в DataTable для обновления столбца.

Сначала вычислите карту:

var RiskValue = "AAA".AsSingleton()
                     .Concat(new[] { "AA", "A", "BBB", "BB", "B", "CCC" }.SelectMany(r => new[] { "+", "", "-" }.Select(suffix => r + suffix)))
                     .Concat(new[] { "CC", "C", "D" })
                     .Select((r, v) => new { r, v })
                     .ToDictionary(rv => rv.r, rv => rv.v);

Затем обновите столбец разницы значениями:

foreach (var r in dt.AsEnumerable())
    r["Risk Difference"] = RiskValue[r.Field<string>("Current risk")] - RiskValue[r.Field<string>("Forward risk")];

PS При вычислении моей карты используется расширение для преобразования объекта в IEnumerable<T>, но вы также можете использовать new[] { object }.

public static IEnumerable<T> AsSingleton<T>(this T first) {
    yield return first;
}
1 голос
/ 02 августа 2020

Вы можете использовать массив или List<T>, или любую коллекцию любого типа, которую вы действительно хотите.

// insert what ever you like (this was only an example)
private static readonly string[] _array = new[] {"AAA", "AA+", "AA", "A+", "A", "BBB", "BB+"};

private static int Difference(string a, string b)
   => Array.IndexOf(_array, a) - Array.IndexOf(_array, b);

...

Console.WriteLine(Difference("AAA", "A+"));

Примечание : Это был только пример и одно из многих решений, которые вы могли создать. В этом примере вы можете заполнить массив по своему усмотрению или использовать любую коллекцию, которая вам нравится. У вас должна быть некоторая отказоустойчивость и проверка ввода и т. Д.

Другой вариант - Словарь строк и целых чисел.

0 голосов
/ 02 августа 2020

Сначала я бы создал класс и сопоставил значения каждого риска. Основываясь на показанных примерах для группы A, я пришел к выводу, что сопоставление значений было таким:

  • A- Value: 0
  • A Value: 1
  • Значение A +: 2
  • Значение AA-: 3
  • Значение AA: 4
  • Значение AA +: 5
  • Значение AAA: 6

Класс для хранения этих данных:

class Score
{
    public int Value { get; set; }
    public string Name { get; set; }
}

Пример кода показывает добавление группы «A» в список, а также правильное вычисление разницы рисков.

        List<Score> scoreList = new List<Score>();
        scoreList.Add(new Score { Name = "A-", Value = 0 });
        scoreList.Add(new Score { Name = "A", Value = 1 });
        scoreList.Add(new Score { Name = "A+", Value = 2 });
        scoreList.Add(new Score { Name = "AA-", Value = 3 });
        scoreList.Add(new Score { Name = "AA", Value = 4 });
        scoreList.Add(new Score { Name = "AA+", Value = 5 });
        scoreList.Add(new Score { Name = "AAA", Value = 6 });

        //If Current = AAA and Forward = AA+ --> Difference = -1
        var difference = scoreList.SingleOrDefault(i => i.Name == "AA+").Value - scoreList.SingleOrDefault(i => i.Name == "AAA").Value;

        //If Current = AAA and Forward = AAA-- > Difference = 0
        var difference1 = scoreList.SingleOrDefault(i => i.Name == "AAA").Value - scoreList.SingleOrDefault(i => i.Name == "AAA").Value;

        //If Current = AAA and Forward = AA-- > Difference = -2
        var difference2 = scoreList.SingleOrDefault(i => i.Name == "AA").Value - scoreList.SingleOrDefault(i => i.Name == "AAA").Value;

        //If Current = AAA and Forward = AA - --> Difference = -3
        var difference3 = scoreList.SingleOrDefault(i => i.Name == "AA-").Value - scoreList.SingleOrDefault(i => i.Name == "AAA").Value;

        //If Current = AA + and Forward = AAA-- > Difference = +1
        var difference4 = scoreList.SingleOrDefault(i => i.Name == "AAA").Value - scoreList.SingleOrDefault(i => i.Name == "AA+").Value;

        //If Current = AA and Forward = AAA-- > Difference = +2
        var difference5 = scoreList.SingleOrDefault(i => i.Name == "AAA").Value - scoreList.SingleOrDefault(i => i.Name == "AA").Value;

        //If Current = A and Forward = AAA-- > Difference = +5
        var difference6 = scoreList.SingleOrDefault(i => i.Name == "AAA").Value - scoreList.SingleOrDefault(i => i.Name == "A").Value;

Надеюсь, это поможет вам начать работу.

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