我有一个与此非常相似的列表(但示例已简化):
public class TimeEntry
{
public int entrydate { get; set; } //UNIX Timestamp
public string name { get; set; }
public string timespent { get; set; } //Be aware this is a string, not an int or date - [hh]:mm (Hours can go above 24)
}
List<TimeEntry> entryTable = new List<TimeEntry>();
//This layout is fictional and just a representation of my List<TimeEntry>
[entrydate: "1540364988", name: "Time1", timespent: "0:30"],
[entrydate: "1540304400", name: "Time2", timespent: "0:25"],
[entrydate: "1540307400", name: "Time1", timespent: "0:10"],
[entrydate: "1540300010", name: "Time3", timespent: "0:40"],
[entrydate: "1540365000", name: "Time1", timespent: "1:10"],
[entrydate: "1540367500", name: "Time3", timespent: "0:20"],
[entrydate: "1540354500", name: "Time4", timespent: "0:30"]
我想合并每个条目,以便每个唯一的 name 条目每天都有总计。
例如
[entrydate: "1540364988", name: "Time1", timespent: "0:30"],
[entrydate: "1540307400", name: "Time1", timespent: "0:10"],
[entrydate: "1540365000", name: "Time1", timespent: "1:10"]
将成为
[entrydate: "1540252800", name: "Time1", timespent: "0:10"],
[entrydate: "1540339200", name: "Time1", timespent: "1:40"]
我将如何高效地做到这一点?我们正在谈论450,000条记录,我正在考虑仅使用一个循环,但是让一个循环运行450,000次,在每个循环中,我们需要遍历已经存储的所有记录,以查看是否应该计数而不是添加新记录听起来效率低下且缓慢。
不需要完整的代码,但是我很想听听别人对此的看法或解决方案。尽管每一点帮助都值得赞赏 谢谢
编辑:
由于该问题因信息不足而被搁置,因此以下是有关我的问题的更多信息:
目标:合并来自同一天且共享相同名称
的每个条目时间戳记位于 UTC 中,并且一天的时间为 00:00:00到23:59:99。
答案 0 :(得分:1)
基本上,您需要将entrydate
转换为全天值,然后按名称和全天对条目进行分组,然后计算每组的时间。
以下代码完成了所有操作。
entrydate
由TrimUnixTimestampToDate
完成
GroupBy
函数使用名称和日期的聚合键完成的
通过将每个timespent
通过TimeSpan
转换为ToTimeSpan
并将它们与AddTimespans
一起添加来计算时间
/
List<TimeEntry> TimeEntryProcessing()
{
var entries = new List<TimeEntry>
{
new TimeEntry{ entrydate = 1540364988, name = "Time1", timespent = "0:30"},
new TimeEntry{ entrydate = 1540304400, name = "Time2", timespent = "0:25"},
new TimeEntry{ entrydate = 1540307400, name = "Time1", timespent = "0:10"},
new TimeEntry{ entrydate = 1540300010, name = "Time3", timespent = "0:40"},
new TimeEntry{ entrydate = 1540365000, name = "Time1", timespent = "1:10"},
new TimeEntry{ entrydate = 1540367500, name = "Time3", timespent = "0:20"},
new TimeEntry{ entrydate = 1540354500, name = "Time4", timespent = "0:30"}
};
return entries
.GroupBy(x => new { x.name, date = TrimUnixTimestampToDate(x.entrydate) })
.Select(x =>
{
var time = AddTimespans(x.Select(y => ToTimeSpan(y.timespent)));
return new TimeEntry
{
entrydate = x.Key.date,
name = x.Key.name,
timespent = $"{(int)time.TotalHours}:{time.Minutes}"
};
})
// in case you need an order... you didn't mention it
.OrderBy(x => x.entrydate).ThenBy(x => x.name)
.ToList();
}
TimeSpan AddTimespans(IEnumerable<TimeSpan> enumerable)
{
return new TimeSpan(enumerable.Sum(x => x.Ticks));
}
TimeSpan ToTimeSpan(string timespent)
{
var parts = timespent.Split(':');
return new TimeSpan(int.Parse(parts[0]), int.Parse(parts[1]), 0);
}
int TrimUnixTimestampToDate(int entrydate)
{
DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
return (int)dtDateTime.AddSeconds(entrydate).Date.Subtract(dtDateTime).TotalSeconds;
}