У меня есть список объектов ViewsHistory, который отсортирован по UtcNow:

var views = List<ViewHistory>

Класс просмотра истории:

public class ViewHistory
{
    [PrimaryKey]
    public string YYMMDD { get; set; }
    public int UtcNow { get; set; }
    public int Learn { get; set; }
    public int Practice { get; set; }
    public int Quiz { get; set; }
}

Есть ли способ с помощью LINQ, чтобы я мог создать новый список, суммирующий итоги для обучения, практики и викторины по YYMM?

c#
0
Alan2 31 Май 2019 в 07:12

2 ответа

Лучший ответ

Решение

var views = new List<ViewHistory>
{
    new ViewHistory {YYMMDD = "190515", Learn = 1, Practice = 2, Quiz = 3},
    new ViewHistory {YYMMDD = "190514", Learn = 5, Practice = 6, Quiz = 7},
    new ViewHistory {YYMMDD = "190415", Learn = 100, Practice = 110, Quiz = 120},
    new ViewHistory {YYMMDD = "190414", Learn = 150, Practice = 160, Quiz = 170}
};

var monthlyTotals = views.GroupBy(
    v => v.YYMMDD.Substring(0, 4),
    v => v,
    (yearMonth, groupedViews) =>
        new
        {
            YearMonth = yearMonth,
            LearnSum = groupedViews.Sum(view => view.Learn),
            PracticeSum = groupedViews.Sum(view => view.Practice),
            QuizSum = groupedViews.Sum(view => view.Quiz)
        }).ToList();

Полученные результаты

monthlyTotals (копируется из окна Visual Studio Locals при отладке)

monthlyTotals   Count = 2   System.Collections.Generic.List<<>f__AnonymousType0<string, int, int, int>>
    [0] { YearMonth = "1905", LearnSum = 6, PracticeSum = 8, QuizSum = 10 } <Anonymous Type>
    [1] { YearMonth = "1904", LearnSum = 250, PracticeSum = 270, QuizSum = 290 } <Anonymous Type>

Скорее не использовать анонимные типы?

И, конечно, если вы предпочитаете не использовать анонимный тип, вы можете определить новый класс (например, MonthlyViewTotals) и создать вместо него список из них для вашего monthlyTotals следующим образом:

var monthlyTotals = views.GroupBy(
    v => v.YYMMDD.Substring(0, 4),
    v => v,
    (yearMonth, groupedViews) =>
        new MonthlyViewTotals        // <-- no more anonymous types
        {
            YearMonth = yearMonth,
            LearnSum = groupedViews.Sum(view => view.Learn),
            PracticeSum = groupedViews.Sum(view => view.Practice),
            QuizSum = groupedViews.Sum(view => view.Quiz)
        }).ToList();
1
egnomerator 31 Май 2019 в 05:48

Вы можете достичь этого с помощью GroupBy выражения LINQ:

 var views = new List<ViewHistory>();
            views.Add(new ViewHistory {YYMMDD = "190530", Learn = 20, Practice = 1, Quiz = 30});
            views.Add(new ViewHistory { YYMMDD = "190531", Learn = 1, Practice = 1, Quiz = 30 });
            views.Add(new ViewHistory { YYMMDD = "190529", Learn = 2, Practice = 1, Quiz = 30 });
            views.Add(new ViewHistory { YYMMDD = "190410", Learn = 2, Practice = 1, Quiz = 30 });
            var newViews = views.GroupBy(t => t.YYMMDD.Substring(0, 4))
                .Select(t => new
                {
                    yymm = t.Key,
                    learnSum = t.Select(f => f.Learn).Sum(),
                    practiceSum = t.Select(f => f.Practice).Sum(),
                    quizSum = t.Select(f => f.Quiz).Sum()
                }).ToList();

< Сильный > Результат

{ yymm = "1905", learnSum = 23, practiceSum = 3, quizSum = 90 },
{ yymm = "1904", learnSum = 2, practiceSum = 1, quizSum = 30 }
1
mexanich 31 Май 2019 в 04:52