C#LINQ-对字典进行排序和分组<;字符串,日期时间>;按最大组大小的日期
我希望从C#LINQ-对字典进行排序和分组<;字符串,日期时间>;按最大组大小的日期,linq,datetime,sorting,group-by,Linq,Datetime,Sorting,Group By,我希望从字典中创建批,并具有以下约束: 批处理中的所有项目共享相同的日期 单个批次中最多只能有X个项目。如果有多个项目的日期相同,则必须创建另一批 我已经计算出了以下逻辑,但我想知道是否有其他更简洁的方法来处理linq using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace dictionary_sort_by_value_test { class P
字典
中创建批,并具有以下约束:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace dictionary_sort_by_value_test
{
class Program
{
static void Main(string[] args)
{
int maxBatchSize = 3;
Dictionary<string, DateTime> secs = new Dictionary<string, DateTime>();
secs.Add("6571 JT", new DateTime(2011, 1, 10));
secs.Add("6572 JT", new DateTime(2011, 1, 12));
secs.Add("6573 JT", new DateTime(2011, 1, 12));
secs.Add("6574 JT", new DateTime(2011, 1, 12));
secs.Add("6575 JT", new DateTime(2011, 1, 10));
secs.Add("6576 JT", new DateTime(2011, 1, 11));
secs.Add("6577 JT", new DateTime(2011, 1, 11));
secs.Add("6578 JT", new DateTime(2011, 1, 11));
secs.Add("6579 JT", new DateTime(2011, 1, 11));
var sorted = secs.OrderBy(o => o.Value).GroupBy(o => o.Value);
foreach (var date in sorted)
{
Console.Write("\nNew batch at {0} \n", date.Key);
int batchsize = 0;
foreach (var sec in date)
{
if (batchsize < maxBatchSize)
{
Console.Write(" {0} {1} \n", sec.Key, sec.Value);
batchsize++;
}
else
{
Console.Write("\nNew batch at {0} \n", date.Key);
Console.Write(" {0} {1} \n", sec.Key, sec.Value);
batchsize = 1;
}
}
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
名称空间字典\u按值排序\u测试
{
班级计划
{
静态void Main(字符串[]参数)
{
int maxBatchSize=3;
Dictionary secs=新字典();
第二节添加(“6571 JT”,新日期时间(2011年1月10日));
第二节添加(“6572 JT”,新日期时间(2011年1月12日));
第二节添加(“6573 JT”,新日期时间(2011年1月12日));
第二节添加(“6574 JT”,新日期时间(2011年1月12日));
第二节添加(“6575 JT”,新日期时间(2011年1月10日));
第二节添加(“6576 JT”,新日期时间(2011年1月11日));
第二节添加(“6577 JT”,新日期时间(2011年1月11日));
第二节添加(“6578 JT”,新日期时间(2011年1月11日));
第二节添加(“6579 JT”,新日期时间(2011年1月11日));
var sorted=secs.OrderBy(o=>o.Value).GroupBy(o=>o.Value);
foreach(已排序的var日期)
{
Write(“\n在{0}\n处的新批处理,date.Key”);
int batchsize=0;
foreach(var秒输入日期)
{
if(batchsize
不是严格使用linq来解决问题,而是一种更简洁的迭代处理方式:
static void Main(string[] args)
{
int maxBatchSize = 3;
Dictionary<string, DateTime> secs = new Dictionary<string, DateTime>();
secs.Add("6571 JT", new DateTime(2011, 1, 10));
secs.Add("6572 JT", new DateTime(2011, 1, 12));
secs.Add("6573 JT", new DateTime(2011, 1, 12));
secs.Add("6574 JT", new DateTime(2011, 1, 12));
secs.Add("6575 JT", new DateTime(2011, 1, 10));
secs.Add("6576 JT", new DateTime(2011, 1, 11));
secs.Add("6577 JT", new DateTime(2011, 1, 11));
secs.Add("6578 JT", new DateTime(2011, 1, 11));
secs.Add("6574 JT", new DateTime(2011, 1, 11));
secs.Add("6579 JT", new DateTime(2011, 1, 11));
secs.Add("6580 JT", new DateTime(2011, 1, 11));
secs.Add("6581 JT", new DateTime(2011, 1, 11));
secs.Add("6582 JT", new DateTime(2011, 1, 11));
secs.Add("6583 JT", new DateTime(2011, 1, 11));
secs.OrderBy(o => o.Value).GroupBy(o => o.Value).ToList().ForEach(date =>
{
Console.Write("\nNew batch at {0} \n", date.Key);
int batchsize = 0;
foreach (var sec in date)
{
if (batchsize >= maxBatchSize)
{
Console.Write("\nNew batch at {0} \n", date.Key);
batchsize = 0;
}
Console.Write(" {0} {1} \n", sec.Key, sec.Value);
batchsize++;
}
});
Console.ReadLine();
}
static void Main(字符串[]args)
{
int maxBatchSize=3;
Dictionary secs=新字典();
第二节添加(“6571 JT”,新日期时间(2011年1月10日));
第二节添加(“6572 JT”,新日期时间(2011年1月12日));
第二节添加(“6573 JT”,新日期时间(2011年1月12日));
第二节添加(“6574 JT”,新日期时间(2011年1月12日));
第二节添加(“6575 JT”,新日期时间(2011年1月10日));
第二节添加(“6576 JT”,新日期时间(2011年1月11日));
第二节添加(“6577 JT”,新日期时间(2011年1月11日));
第二节添加(“6578 JT”,新日期时间(2011年1月11日));
第二节添加(“6574 JT”,新日期时间(2011年1月11日));
第二节添加(“6579 JT”,新日期时间(2011年1月11日));
第二节添加(“6580 JT”,新日期时间(2011年1月11日));
第二节添加(“6581 JT”,新日期时间(2011年1月11日));
第二节添加(“6582 JT”,新日期时间(2011年1月11日));
第二节添加(“6583 JT”,新日期时间(2011年1月11日));
secs.OrderBy(o=>o.Value).GroupBy(o=>o.Value).ToList().ForEach(日期=>
{
Write(“\n在{0}\n处的新批处理,date.Key”);
int batchsize=0;
foreach(var秒输入日期)
{
如果(batchsize>=maxBatchSize)
{
Write(“\n在{0}\n处的新批处理,date.Key”);
batchsize=0;
}
写入(“{0}{1}\n”,秒键,秒值);
batchsize++;
}
});
Console.ReadLine();
}
您可以使用2个GroupBys来完成。首先按日期时间分组,然后按页面分组。我必须显式地指定泛型参数,因为编译器选择了错误的重载,这使得查询代码更长
var groups = secs.GroupBy<KeyValuePair<string, DateTime>, DateTime, string, Group>(
p => p.Value,
p => p.Key,
(d, g) => new Group {
Date = d,
Pages = g.Select((s, i) => new KeyValuePair<string, int>(s, i / maxBatchSize))
.GroupBy<KeyValuePair<string, int>, int, string, Page>(
p => p.Value,
p => p.Key,
(p, g2) => new Page { Id = p, Items = g2.ToList() }) });
foreach (var group in groups)
{
Console.WriteLine("Date: {0}", group.Date);
foreach (var page in group.Pages)
{
Console.WriteLine("Page: {0}", page.Id);
foreach (var key in page.Items)
Console.WriteLine(key);
}
}
var groups=secs.GroupBy(
p=>p.值,
p=>p.键,
(d,g)=>新组{
日期=d,
Pages=g.Select((s,i)=>newkeyvaluepair(s,i/maxBatchSize))
.群比(
p=>p.值,
p=>p.键,
(p,g2)=>新页面{Id=p,Items=g2.ToList()});
foreach(组中的var组)
{
WriteLine(“日期:{0}”,group.Date);
foreach(group.Pages中的变量页)
{
WriteLine(“Page:{0}”,Page.Id);
foreach(page.Items中的var键)
控制台。写入线(键);
}
}
如您所见,我必须定义2个类,因为正如我所说,我必须指定泛型参数,因为使用匿名类型使重载解析选择另一个重载
class Group
{
public DateTime Date;
public IEnumerable<Page> Pages;
}
class Page
{
public int Id;
public IEnumerable<string> Items;
}
类组
{
公共日期时间日期;
公共可数页;
}
类页
{
公共int Id;
公共物品;
}
希望这有帮助。您可以按键分组,然后在结果中按项目索引除以所需的块大小进行分组
var chunkSize = 3;
var sorted = secs
.OrderBy(kv => kv.Key)
.GroupBy(o => o.Value)
.Select(g => new {Chunks = g.Select((o,i) => new {Val = o, Index = i})
.GroupBy(item => item.Index / chunkSize)});
并显示:
foreach(var item in sorted.SelectMany(item => item.Chunks))
{
Console.WriteLine("New batch at " + item.First().Val.Value);
foreach(var element in item)
Console.WriteLine(element.Val.Key);
}
我也看不到您在代码中在何处/如何创建新批处理。您正在计算批次数,但不是每个批次都在创建新批次并将其添加到“结果”中。就我个人而言,你唯一能用LINQ做到这一点的方法就是再打一个平局,这样你也可以按这个分组。或者将逻辑实现为IEnumerable上的扩展方法。这样,它看起来像LINQ,感觉像LINQ,而且它将是LINQ,因为这就是LINQ的实现方式。谢谢。这正是我想要的。看起来不太好看,但我喜欢它,而且很管用。