Как найти пропущенные месяцы из списка месяцев в течение года - PullRequest
1 голос
/ 23 марта 2020

Ниже приведен пример списка продаж, показывающий, сколько денег было заработано за последние 12 месяцев при пропущенных 2 месяцах (может быть больше или меньше).

[{1, 400}, {2,500}, {4, 550}, {5, 425}, {6, 770}, {7, 500}, {9, 300}, {10, 900}, {11, 440}, {12, 620}]

Месяцы в порядке возрастания, поэтому 1 - январь, а 12 - De c. Как я могу обновить этот список в коде, чтобы добавить объект продаж для пропущенных месяцев со значением 0. В этом случае добавление {3, 0} и {8, 0}.

Я получаю их из базы данных и причину некоторых отсутствуют, потому что у них нет записи в базе данных, поэтому я хочу добавить ноль за пропущенные месяцы. Месяц начинается с DateTime.Date.Month.

Ответы [ 2 ]

2 голосов
/ 23 марта 2020

Пытался сделать это как можно ближе к вашей модели

// Example
var yearSales = new Dictionary<int, decimal>
{
    {  1, 100 },
    {  3, 300 },
    {  6, 600 },
};

// Actual logic
var fullMonths = Enumerable.Range(1, 12)
    .ToDictionary(
        month => month,
        month => yearSales.TryGetValue(month, out decimal d) ? d : default
    );
2 голосов
/ 23 марта 2020

Если у вас есть класс, представляющий ваши месяцы:

public class MonthData
{
    public int Month { get; set; }
    public int Money { get; set; }
}

Затем вы можете использовать LINQ, чтобы найти пропущенные месяцы, а затем вставить их в исходный список:

var months = new List<MonthData>
{
    new MonthData {Month = 1, Money = 400},
    new MonthData {Month = 2, Money = 500},
    new MonthData {Month = 4, Money = 550},
    new MonthData {Month = 5, Money = 425},
    new MonthData {Month = 6, Money = 770},
    new MonthData {Month = 7, Money = 500},
    new MonthData {Month = 9, Money = 300},
    new MonthData {Month = 10, Money = 900},
    new MonthData {Month = 11, Money = 440},
    new MonthData {Month = 12, Money = 620}
};

# Find missing months
var missingMonths = Enumerable
    .Range(months.Min(m => m.Month), months.Max(m => m.Month))
    .Except(months.Select(m => m.Month))

# Insert missing months back into months list
foreach (var month in missingMonths)
{
    months.Insert(month - 1, new MonthData { Month = month, Money = 0 });
}

Дополнительно , List<T>.Insert(Int32, T) - это O (N) для вставки. Мы можем улучшить это, используя Dictionary<int, int> для вставки O (1) :

var months = new Dictionary<int, int>
{
    {1, 400},
    {2,500},
    {4, 550},
    {5, 425},
    {6, 770},
    {7, 500},
    {9, 300},
    {10, 900},
    {11, 440},
    {12, 620}
};

var missingMonths = Enumerable
    .Range(months.Keys.Min(), months.Keys.Max())
    .Except(months.Keys);

foreach (var month in missingMonths)
{
    months[month] = 0;
}

А также есть возможность go вернуться на List<MonthData> вниз по линии :

var monthList = months
    .Select(pair => new MonthData { 
        Month = pair.Key, 
        Money = pair.Value 
    })
    .OrderBy(m => m.Month)
    .ToList();

Требуется O (NLogN) * ​​1023 * сортировка с Enumerable.OrderBy, так как словари неупорядочены по своей природе.

Попробуйте dotnetfiddle. net

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