Nano Hash - криптовалюты, майнинг, программирование

Как добавить недостающую последовательность в список по месяцу и году?

Предположим, у нас есть эти значения из базы данных:

  • Месяц: 5, Всего: 100, Год: 2019, Id: 1
  • Месяц: 7, Всего: 45, Год: 2019, Id: 1
  • Месяц: 5, Всего: 55, Год: 2019, Id: 2
  • Месяц: 9, Всего: 110, Год: 2019, Id: 2

Затем мне нужно сгенерировать строки для месяцев 6 и 8, которые отсутствуют в списке с Total: 0 для Id: 1 и Id: 2.

Конечный результат должен быть:

  • Месяц: 5, Всего: 100, Год: 2019, Id: 1
  • Месяц: 6, Всего: 0, Год: 2019, Id: 1
  • Месяц: 7, Всего: 45, Год: 2019, Id: 1
  • Месяц: 5, Всего: 55, Год: 2019, Id: 2
  • Месяц: 6, Всего: 0, Год: 2019, Id: 2
  • Месяц: 7, Всего: 0, Год: 2019, Id: 2
  • Месяц: 8, Всего: 0, Год: 2019, Id: 2
  • Месяц: 9, Всего: 110, Год: 2019, Id: 2

Как я могу сделать это с LINQ и C #? Еще сложнее, если подумать о конце года, т.е. g: 12-й месяц, год: 2019 и 2-й месяц, год: 2020.

Спасибо за любую помощь!

06.05.2019

Ответы:


1

Вы хотите сгруппировать записи по (идентификатору и году) и найти границу (первый месяц и последний месяц) в каждой группе, чтобы заполнить пробелы:

    db.NAME_OF_THE_TABLE
        .ToArray() // materialize the query, since this group by is unlikely to be supported by linq2...
        .GroupBy(x => new { x.Id, x.Year }, (k, g) =>
        {
            var months = new { First = g.Min(x => x.Month), Last = g.Max(x => x.Month) };

            // left join to fill the blank between the records
            return (
                from month in Enumerable.Range(months.First, months.Last - months.First + 1)
                join row in g on month equals row.Month into match
                from x in match.DefaultIfEmpty(new TYPE_OF_RECORD { Id = k.Id, Year = k.Year, Month = month, Total = 0 })
                select x
            );
        })
        .SelectMany(g => g) // flatten the grouping
06.05.2019

2

Использование метода расширения для вычисления количества месяцев между двумя месяцами:

public static class DateTimeExt {
    public static int MonthDiff(this DateTime d1, DateTime d2) => (d1.Year-d2.Year)*12+d1.Month-d2.Month;
}

Вы можете создать диапазон месяцев, а затем заполнить недостающие месяцы. Я использую Dictionary, чтобы узнать, существует ли месяц уже:

var ans = db.GroupBy(r => r.ID)
            .AsEnumerable()
            .SelectMany(rg => {
                var rgd = rg.ToDictionary(r => (r.Month, r.Year));
                var First = rg.Min(r => new DateTime(r.Year, r.Month, 1));
                var Last = rg.Max(r => new DateTime(r.Year, r.Month, 1));
                return Enumerable.Range(0, Last.MonthDiff(First) + 1).Select(moffset => {
                    var wd = First.AddMonths(moffset);
                    return rgd.TryGetValue((wd.Month, wd.Year), out var r) ? r : new { ID = rg.Key, wd.Month, wd.Year, Total = 0 };
                });
            });

AsEnumerable должен извлекать информацию о запросе локально, чтобы остальная часть выполнялась в LINQ to Objects.

07.05.2019

3

Вы можете создать недостающие данные и создать союз. Например,

var list = new []
{
    new Data{Month=5,Total=100,Year=2019,Id=1},
    new Data{Month=7,Total=100,Year=2019,Id=1},
    new Data{Month=5,Total=100,Year=2019,Id=2},
    new Data{Month=9,Total=100,Year=2019,Id=2},
    new Data{Month=2,Total=100,Year=2020,Id=2}
};

var result = list.GroupBy(x=>x.Id)
                    .Select(x=>
                    {
                        var minDate = x.ToList().Select(c=> new DateTime(c.Year,c.Month,1)).Min();
                        var maxDate = x.ToList().Select(c=> new DateTime(c.Year,c.Month,1)).Max();

                        return x.ToList().Union(Enumerable.Range(0, Int32.MaxValue)
                                         .Select(e => minDate.AddMonths(e))
                                         .TakeWhile(e => e <= maxDate)
                                         .Select(e => new Data{Month=e.Month, Total=0,Year=e.Year,Id=x.Key}))
                                         .OrderBy(v=> new DateTime(v.Year,v.Month,1))
                                         .GroupBy(c=>new {c.Month,c.Year})
                                         .Select(g=>g.First());
                    }).SelectMany(v=>v);

Где данные определены как

public class Data
{
    public int Month{get;set;}
    public int Year{get;set;}
    public int Total{get;set;}
    public int Id{get;set;}
}
07.05.2019
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..