Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用于比较的订单日期列表_C#_Arrays_List_Linq_Datetime - Fatal编程技术网

C# 用于比较的订单日期列表

C# 用于比较的订单日期列表,c#,arrays,list,linq,datetime,C#,Arrays,List,Linq,Datetime,我以前在这里问过这个问题: 我认为提议的解决方案很好,直到我的日期清单上的年份结束,遇到了一个问题 我的日期列表(以这种基于字符串的格式-这是数据如何从源API获取到的) 我想在条形图中展示我的数据,以显示3个月的同比比较(按月份顺序)。这意味着我会按顺序排列列表 201711 201811 201712 201812 201801 201901 这样我就可以看到11月、12月和1月的年复一年的条形图 我尝试了问题底部的解决方案,但顺序是这样的(这不是我想要的): 为清楚起见,下个月需要将日期

我以前在这里问过这个问题:

我认为提议的解决方案很好,直到我的日期清单上的年份结束,遇到了一个问题

我的日期列表(以这种基于字符串的格式-这是数据如何从源API获取到的)

我想在条形图中展示我的数据,以显示3个月的同比比较(按月份顺序)。这意味着我会按顺序排列列表

201711
201811
201712
201812
201801
201901
这样我就可以看到11月、12月和1月的年复一年的条形图

我尝试了问题底部的解决方案,但顺序是这样的(这不是我想要的):

为清楚起见,下个月需要将日期列表向前移动:

我想要的第一个月总是比当前月早两个月

201712
201812
201801
201901
201802
201902


我可以通过使用
GroupBy
来实现您的目标

var rowsInOrder = new List<string>();
foreach (var grouping in dates.GroupBy(s =>
        DateTime.ParseExact(s, "yyyyMM", CultureInfo.CurrentCulture).Month))
{
    rowsInOrder.AddRange(grouping.OrderBy(s => s));
};
var rowsInOrder=new List();
foreach(var)以日期分组。GroupBy(s=>
DateTime.ParseExact(s,“yyyyMM”,CultureInfo.CurrentCulture.Month))
{
rowsInOrder.AddRange(grouping.OrderBy(s=>s));
};
您也可以使用相同的逻辑订购月份:

var rowsInOrder = new List<string>();
foreach (var grouping in dates
    .OrderBy(s => DateTime.ParseExact(s, "yyyyMM", CultureInfo.CurrentCulture).Month).GroupBy(s =>
        DateTime.ParseExact(s, "yyyyMM", CultureInfo.CurrentCulture).Month))
{
    rowsInOrder.AddRange(grouping.OrderBy(s => s));
}
var rowsInOrder=new List();
foreach(var)按日期分组
.OrderBy(s=>DateTime.ParseExact(s,“yyyyMM”,CultureInfo.CurrentCulture).Month).GroupBy(s=>
DateTime.ParseExact(s,“yyyyMM”,CultureInfo.CurrentCulture.Month))
{
rowsInOrder.AddRange(grouping.OrderBy(s=>s));
}

您可以使用这种查找方法,首先确定月份组:

var monthLookup = dateList
    .Select(s => new{String = s, Date = DateTime.ParseExact(s, "yyyyMM", CultureInfo.CurrentCulture)})
    .OrderBy(x => x.Date)  // not necessary in your sample data but i assume it's desired
    .ToLookup(x=> x.Date.Month);
var rowsInOrder = monthLookup.SelectMany(x => x).Select(x => x.String);

在我看来,这已经足够了:

var rowsInOrder = dates.OrderBy(x => x).GroupBy(x => x.Substring(4)).SelectMany(x => x);

根本没有必要乱搞解析日期。这是一种简单的字符串排序和分组方式。

因此,您必须处理一系列对象,其中每个对象都有一个格式为yyyyMM的日期属性,类型为string。你想从中提取一些数据

您的日期格式与语言无关。不管你的电脑是英国的还是中国的。Date属性的格式始终为yyyyMM

这使得将其转换为DateTime格式变得相当容易,从而可以轻松访问年份和月份

const string dateTimeFormat = "yyyyMM";
CultureInfo provider = CultureInfo.InvariantCulture;
var dateList = ...      // your original list of items with the string Date property

var itemsWithYearMonth = dateList.Select(item => new
{
    DateTime = DateTime.ParseExact(item, dateTimeFormat, provider)
    ... // select other items you need for your bar chart
});
现在,给定StartYear/Month、NrOfYears和nrofmonth,您希望将dateTimeItems分组为同一个月的组

例如,从2018-11年开始,我希望团队连续三年有四个月的时间(是的,是的,我知道在你最初的请求中只有三个月,两年,但为什么要限制自己,让我们让你的代码重复使用):

奖励积分:我们将通过年度边界

因此,输入:

var itemsWithYearMonth = ... // see above
int startYear = ...
int startMonth = ...
int nrOfMonths = ...    
int nrOfYears = ...
我们将使用相同的月份制作项目组。我们不想要一年中所有的月份,我们只想要几个月。如果我们想要从第11个月开始的3个月,我们需要将组保留为第11、12、1个月

var desiredMonths = Enumerable.Range(startMonth, nrOfMonths)   // example: 11, 12, 13
    .Select(monthNr => 1 + ((monthNr-1) % 12));                // 11, 12, 1
根据您的输入,我们不需要所有月份,我们只希望年/月大于起始月份

DateTime startMonth = new DateTime(startYear, startMonth, 1);
最简单的方法是只保留日期等于或大于startMonth的项目的输入源,并且只获取每组的前几年项目。这样,如果您像我在示例中所做的那样通过年份边界,您将获得正确的项目数

var result = itemsWithYearMonth
    // keep only the items newer than startMonth
    .Where(item => item.DateTime >= startMonth)

    // group by same month:
    .GroupBy(item => item.DateTime.Month,
    (month, itemsWithThisMonth) => new
    {
        Month = month,        // in my example: 11, 12, 1, ...

        // in every group: take the first nrOfYears items:
        Items = itemsWithThisMonth
                // order by ascending year
                .OrderBy(itemWithThisMonth => itemWithThisMonth.Year)
                // no need to order by Month, all Months are equal in this group
                .Take(nrOfYears)
                .ToList(),
     })
     // keep only the desired months:
     .Select(group => desiredMonth.Contains(group.Month));
现在你们有了小组:

group of month 11, with data of years 2018, 2019, 2020, 2021
group of month 12, with data of years 2018, 2019, 2020, 2021
group of month 01, with data of years 2019, 2020, 2021, 2022

@幸运的是,这些日期来自于字符串格式的API。我需要按照上面的顺序重新排列数据,以显示我需要的方式to@mjwills我已经添加了下个月的列表。谢谢你的提示。我要试一试@mjwills-是的,它总是按时间顺序来的。我需要根据我的比较要求重新安排。@Rango这对我来说很好。非常感谢。在
ToLookup
上自我阅读的注意事项,这样你就可以一直得到前几年的结果,你也可以对你不使用的项目进行分组和订购,每个组都包含你想要的更多年份?@haraldcopoolse:如果需要,你可以添加
DateTime
-轻松过滤:
日期列表。选择(相同)。在哪里(x=>x.Date>=minDate和y.Date不太容易:他想要几个小组的一个酒吧,每个小组包含一年中的几个月。例如,2018年,从11月开始,3个月,4年。所以小组11月:2018-11,2019-11,2020-11,2021-11。小组12月:2018-12,2019-12,2020-12,2021-12;小组1月:2019-01,2020-01,2021-01,2022-01.因此,第2021-08号、第2021-09号和第2021-10号决定
var desiredMonths = Enumerable.Range(startMonth, nrOfMonths)   // example: 11, 12, 13
    .Select(monthNr => 1 + ((monthNr-1) % 12));                // 11, 12, 1
DateTime startMonth = new DateTime(startYear, startMonth, 1);
var result = itemsWithYearMonth
    // keep only the items newer than startMonth
    .Where(item => item.DateTime >= startMonth)

    // group by same month:
    .GroupBy(item => item.DateTime.Month,
    (month, itemsWithThisMonth) => new
    {
        Month = month,        // in my example: 11, 12, 1, ...

        // in every group: take the first nrOfYears items:
        Items = itemsWithThisMonth
                // order by ascending year
                .OrderBy(itemWithThisMonth => itemWithThisMonth.Year)
                // no need to order by Month, all Months are equal in this group
                .Take(nrOfYears)
                .ToList(),
     })
     // keep only the desired months:
     .Select(group => desiredMonth.Contains(group.Month));
group of month 11, with data of years 2018, 2019, 2020, 2021
group of month 12, with data of years 2018, 2019, 2020, 2021
group of month 01, with data of years 2019, 2020, 2021, 2022