我有一个特定类的项目列表(特别是IEnumerable):
internal class MyItem
{
public MyItem(DateTime timestamp, string code)
{
Timestamp= timestamp;
Code = code;
}
public DateTime Timestamp { get; private set; }
public string Code { get; private set; }
}
在此列表中,将有多个具有相同代码的项目。每个都有一个时间戳,可能是也可能不是唯一的。
我试图检索MyItem的词典(Dictionary<string, MyItem>
),其中键是与该项目相关联的代码。
public Dictionary<string, MyItem> GetLatestCodes(IEnumerable<MyItem> items, DateTime latestAllowableTimestamp)
鉴于此签名,如何为每个代码检索最接近MyItem
但不是latestAllowableTimestamp
之后的时间戳的IEnumerable<MyItem> items = new List<MyItem>{
new MyItem(DateTime.Parse("1/1/2014"), "1"),
new MyItem(DateTime.Parse("1/2/2014"), "2"),
new MyItem(DateTime.Parse("1/3/2014"), "1"),
new MyItem(DateTime.Parse("1/4/2014"), "1"),
new MyItem(DateTime.Parse("1/4/2014"), "2")};
?
例如,给出以下输入:
latestAllowableTimestamp
如果Timestamp | Code
----------------
1/3/2014 | 1
1/2/2014 | 2
是2014年1月3日,则结果将仅包含以下项目:
latestAllowableTimestamp
我可以设法将列表过滤到var output = items.Where(t => (t.Timestamp <= latestAllowableTimestamp)).GroupBy(t => t.Code);
之前的那些时间戳,但我不太了解linq以便为每个代码选择最新的代码并将其插入字典中。< / p>
{{1}}
此时,我最终选择了两个小组,但不知道如何在每个小组中选择一个项目。
答案 0 :(得分:3)
这是您尝试编写的实际方法。它甚至会返回字典和所有内容:
static Dictionary<string, MyItem> GetLatestCodes(
IEnumerable<MyItem> items, DateTime latestAllowableTimestamp)
{
return items
.Where(item => item.TimeStamp <= latestAllowableTimestamp)
.GroupBy(item => item.Code)
.Select(group => group
.OrderByDescending(item => item.TimeStamp)
.First())
.ToDictionary(item => item.Code);
}
答案 1 :(得分:2)
这是你应该在你的问题中发布的部分(正如LB指出的那样)
var list = new List<MyItem>()
{
new MyItem(){ code = "1" , timestamp = new DateTime(2014,1,1)},
new MyItem(){ code = "2" , timestamp = new DateTime(2014,1,2)},
new MyItem(){ code = "1" , timestamp = new DateTime(2014,1,3)},
new MyItem(){ code = "1" , timestamp = new DateTime(2014,1,4)},
new MyItem(){ code = "2" , timestamp = new DateTime(2014,1,4)}
};
DateTime latestAllowableTimestamp = new DateTime(2014, 1, 3);
这是我的回答
var result = list.GroupBy(x => x.code)
.Select(x => x.OrderByDescending(y => y.timestamp)
.FirstOrDefault(z => z.timestamp <= latestAllowableTimestamp))
.ToList();
答案 2 :(得分:0)
要创建词典,可以像这样构建您的查询:
var newDict = items.Where(a => a.Timestamp <= latestAllowableTimestamp)
.GroupBy(b => b.Timestamp)
.ToDictionary(c => c.First().Timestamp, c => c.First());
这应该根据您的数据创建一个字典,没有重复的日子。请注意,如果没有GroupBy
查询,您就会引发异常,因为ToDictionary
并未过滤掉已经看过的密钥。
然后,如果您想为任何给定的代码编号只获得一个MyItem,您可以使用此查询:
newDict.Select(a => a.Value)
.OrderByDescending(b => b.Timestamp)
.GroupBy(c => c.Code)
.Select(d => d.First());
FirstOrDefault
查询将只返回每个组中的一个元素。这将为您提供最接近任何给定代码的最新日期的MyItem。