在2个列表之间以历史方式比较值,如果元素来自第一个列表,则递增该值;如果元素来自第二个列表,则递减该值-C# [英] Comparing values in historic manner between 2 lists and increment the values if element is from first list or decerement if it's from second list - C#

查看:62
本文介绍了在2个列表之间以历史方式比较值,如果元素来自第一个列表,则递增该值;如果元素来自第二个列表,则递减该值-C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要准备一张图表,其中我必须显示3条线.

I need to prepare a chart wherein I'm required to show 3 lines. One for showing new issues for a week, second for closed issues for a week and third for total accumulative open issues from first week to last week.

基于这个原因,我已经准备好一个查询,并且能够成功创建2个单独的列表-一个列表维护每周新发行期刊的数量,第二个列表维护每周封闭发行的期刊的数量.

For this reason, I have prepared a query and was able to create 2 separate lists successfully - one list maintains the weekly count of new issues and second list maintains the weekly count of closed issues.

以下是第一个列表的示例数据(其中包含新问题):

Here is the sample data for first list (one which maintains new issues) :

        [0]: { Week = {6/14/2015 12:00:00 AM}, Count = 1 }
        [1]: { Week = {3/5/2017 12:00:00 AM}, Count = 1 }
        [2]: { Week = {5/21/2017 12:00:00 AM}, Count = 4 }
        [3]: { Week = {6/4/2017 12:00:00 AM}, Count = 7 }
        [4]: { Week = {6/11/2017 12:00:00 AM}, Count = 4 }
        [5]: { Week = {6/25/2017 12:00:00 AM}, Count = 7 }
        [6]: { Week = {7/9/2017 12:00:00 AM}, Count = 3 }

从以上数据中,我可以获得特定一周内未解决问题的总数.

From the above data, I get the total count of open issues for a particular week.

注意:对于这两个列表,星期"值都包含星期天的日期. 因为我需要一周从星期一开始,同时在图表中显示数据.

Note: For both these lists the Week values contain date which falls on Sunday. As I need the week to start on Monday while displaying data in the chart.

类似地,针对第二个列表的样本数据(一个用于维护已解决问题的列表):

Similarly for sample data for second list (one which maintains closed issues) :

[0]: { Week = {12/13/2015 12:00:00 AM}, Count = 1 }
[1]: { Week = {7/9/2017 12:00:00 AM}, Count = 3 }
[2]: { Week = {6/18/2017 12:00:00 AM}, Count = 2 }
[3]: { Week = {7/23/2017 12:00:00 AM}, Count = 8 }
[4]: { Week = {10/1/2017 12:00:00 AM}, Count = 6 }
[5]: { Week = {8/6/2017 12:00:00 AM}, Count = 3 }
[6]: { Week = {9/17/2017 12:00:00 AM}, Count = 1 }

从以上数据中,我可以得出特定一周内已解决问题的总数.

From the above data, I get total count of closed issues for a particular week.

这是这些列表的代码:

var openIssuesList = getDetails.Where(x => x.ChangedTo == "Open").Select(x => new { Week = x.Date.AddDays(x.Date.DayOfWeek == DayOfWeek.Sunday ? 0 : 7 - (int)x.Date.DayOfWeek).Date, Detail = x }).GroupBy(x => x.Week).Select(x => new { Week = x.Key, Count = x.Count() }).ToList();


var closedIssuesList = getDetails.Where(x => x.ChangedTo == "Closed").Select(x => new { Week = x.Date.AddDays(x.Date.DayOfWeek == DayOfWeek.Sunday ? 0 : 7 - (int)x.Date.DayOfWeek).Date, Detail = x }).GroupBy(x => x.Week).Select(x => new { Week = x.Key, Count = x.Count() }).ToList();

现在剩下的最后一件事情是,使用这两个列表中的值创建一个新列表,其中的值应包含一周内所有未解决问题的数据.

Now the final piece that remains is to create a new list by using the values from these 2 lists which should contain data for total open issues for a week.

说明:

  1. 我需要以历史的方式(最旧到最新)比较上述2个列表中的星期值.
  2. 从这两个列表中
  3. 获取最早的一周值. (根据上面的示例数据,应该是2015年6月14日,该数据位于openIssuesList中.)以这种方式继续从上述2个列表中提取星期(从最旧到最新).
  4. 如果周值来自第一个列表,即 openIssuesList ,则通过添加计数"值来增加计数" 与先前获取的元素(现在存在于新的第三列表中)(如果有)的计数值.
  5. 如果星期值来自第二个列表,即 closedIssuesList ,则通过减去其计数值计数计数与先前获取的元素(现在存在于新的第三列表中)(如果有)的计数值.
  6. 如果星期值相等(如样本数据中的2017年7月9日),则首先 添加 openIssues 列表,其中包含先前获取的元素(现在在新的第三列表中)(如果有),然后减去新计算的值 closedIssues 列表的 Count 值.
  1. I need to compare the week values from the above 2 lists in historic manner(oldest to newest).
  2. Fetch the oldest week value of all from both of these lists. (From the sample data above it should be 6/14/2015 which is in openIssuesList.) Keep fetching weeks (from oldest to newest) in this manner from the above 2 lists.
  3. If week values are from first list i.e openIssuesList then increment the Count value by adding it's Count value with the Count value of previously fetched element (now present in the new third list) if any.
  4. If week values are from second list i.e closedIssuesList then decrement the Count value by subtracting it's Count value with the Count value of previously fetched element (now present in the new third list) if any.
  5. If the week values are equal (like 7/9/2017 from sample data), then first add the Count value of the openIssues list with the previously fetched element (now present in the new third list) if any and then subtract this newly calculated value with the Count value of the closedIssues list .

因此,从上面提供的示例数据中,这是新列表的外观:

So from the above provided sample data here's how the new list should like :

[0]: { Week = {6/14/2015 12:00:00 AM}, Count = 1 }    // 0+1 = 0 : Oldest week value of all - (fetched from openIssuesList)
[1]: { Week = {12/13/2015 12:00:00 AM}, Count = 0 }  // 1-1 = 0  (fetched from closedIssuesList)
[2]: { Week = {3/5/2017 12:00:00 AM}, Count = 1 }  // 0+1 = 1 - (fetched from openIssuesList)
[3]: { Week = {5/21/2017 12:00:00 AM}, Count = 5 }  // 1+4 = 5 - (fetched from openIssuesList)
[4]: { Week = {6/4/2017 12:00:00 AM}, Count = 12 }  // 5+7 = 12 - (fetched from openIssuesList)
[5]: { Week = {6/11/2017 12:00:00 AM}, Count = 16}  // 12+4 = 16 - (fetched from openIssuesList)
[6]: { Week = {6/18/2017 12:00:00 AM}, Count = 14 }  // 16-2 = 14  (fetched from closedIssuesList)
[7]: { Week = {6/25/2017 12:00:00 AM}, Count = 21 } //14+7 = 21  (fetched from openIssuesList)
[8]: { Week = {7/9/2017 12:00:00 AM}, Count = 21 }   // These is common week from both lists. So 20 + (openIssuesList Count value) - (closedIssuesList Count value) i.e [21 + 3 - 3 = 21].
[9]: { Week = {7/23/2017 12:00:00 AM}, Count = 13 }  // 21-8 = 13  (fetched from closedIssuesList)
[10]: { Week = {8/6/2017 12:00:00 AM}, Count = 10 }   // 13-3 = 10  (fetched from closedIssuesList)
[11]: { Week = {9/17/2017 12:00:00 AM}, Count = 9 }    // 10-1 = 9  (fetched from closedIssuesList)
[12]: { Week = {10/1/2017 12:00:00 AM}, Count = 3 }    // 9-6 = 3  (fetched from closedIssuesList)

根据以上数据,请参阅此列表的第8个元素. 此列表中的星期7/9/2017在openIssuesList(第6个元素)和closedIssuesList(第2个元素)中很常见

From the above data kindly see the 8th element of this list. The week in this list 7/9/2017 was common from both the openIssuesList (6th element) and closedIssuesList (2nd element)

实现此列表的代码是什么?

What would be the code to achieve this list?

注意:我必须从这些列表中的所有DateTime值中删除代码中的Time元素值.因此,所有日期值都会在这些列表中的12:00:00 AM出现.

推荐答案

按周对所有问题进行分组,然后根据当前总数以及给定一周的未解决问题和未解决问题的总和来计算计数:

Group all issues by week and then calculate count depending on current total count and sum of open and closed issues for given week:

int totalCount = 0;
var issuesByWeek = from issue in getDetails
                   where issue.ChangedTo == "Open" || issue.ChangedTo == "Closed"
                   group issue by issue.Date.EndOfWeek() into g
                   orderby g.Key
                   select new
                   {
                       Week = g.Key,
                       Count = totalCount += g.Sum(i => i.ChangedTo == "Open" ? 1 : -1)
                   };

您不需要两个列表即可计算此统计信息.如果您出于其他目的需要这些列表,则只需连接它们并使用

You don't need two lists for calculating this stats. If you need these lists for another purpose, then you can simply concat them and use

from issue in openIssuesList.Concat(closedIssuesList)


三个星期的测试数据


Test data for three weeks

var issues = new[]
{
    new Issue { Date = DateTime.Today.AddDays(-16), ChangedTo = "Open" },
    new Issue { Date = DateTime.Today.AddDays(-15), ChangedTo = "Unknown" },
    new Issue { Date = DateTime.Today.AddDays(-15), ChangedTo = "Open" },
    new Issue { Date = DateTime.Today.AddDays(-9), ChangedTo = "Closed" },
    new Issue { Date = DateTime.Today.AddDays(-8), ChangedTo = "Open" },
    new Issue { Date = DateTime.Today.AddDays(-6), ChangedTo = "Closed" },
    new Issue { Date = DateTime.Today.AddDays(-5), ChangedTo = "Closed" }
};

输出:

[
  { "Week": "2017-10-22T00:00:00+03:00", "Count": 2 }, // 0 + 2
  { "Week": "2017-10-29T00:00:00+03:00", "Count": 1 }, // 2 + 1 - 2
  { "Week": "2017-11-05T00:00:00+03:00", "Count": 0 }  // 1 - 1
]


使用扩展方法以提高可读性:


Extension method is used for readability:

public static class DateTimeExtensions
{
    public static DateTime EndOfWeek(this DateTime date) => 
       date.AddDays(date.DayOfWeek == DayOfWeek.Sunday ? 0 : 7 - (int)date.DayOfWeek).Date;
}

注意:考虑使用enum代替问题字符串

Note: instead of string consider to use enum for issues statuses

这篇关于在2个列表之间以历史方式比较值,如果元素来自第一个列表,则递增该值;如果元素来自第二个列表,则递减该值-C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆