【发布时间】:2018-09-27 12:09:40
【问题描述】:
我有一个自定义类ModeTime的列表,其结构如下:
private class ModeTime
{
public DateTime Date { get; set; }
public string LineName { get; set; }
public string Mode { get; set; }
public TimeSpan Time { get; set; }
}
在这个列表中我有一些项目,它们的LineName 和Mode 是相同的,它们被一一写在列表中。我需要对这些项目的Time 属性求和,并将其替换为一个具有Time 属性总和的项目而不更改LineName 和Mode,Date 应该取自替换项目的第一个。下面我举个例子:
Original: Modified:
Date | LineName | Mode | Time Date | LineName | Mode | Time
01.09.2018 | Line1 | Auto | 00:30:00 01.09.2018 | Line1 | Auto | 00:30:00
01.09.2018 | Line2 | Auto | 00:10:00 01.09.2018 | Line2 | Auto | 00:15:00
01.09.2018 | Line2 | Auto | 00:05:00 01.09.2018 | Line2 | Manual | 00:02:00
01.09.2018 | Line2 | Manual | 00:02:00 01.09.2018 | Line2 | Auto | 00:08:00
01.09.2018 | Line2 | Auto | 00:08:00 01.09.2018 | Line1 | Manual | 00:25:00
01.09.2018 | Line1 | Manual | 00:25:00 01.09.2018 | Line2 | Auto | 00:24:00
01.09.2018 | Line2 | Auto | 00:05:00 02.09.2018 | Line1 | Auto | 00:05:00
02.09.2018 | Line2 | Auto | 00:12:00
02.09.2018 | Line2 | Auto | 00:07:00
02.09.2018 | Line1 | Auto | 00:05:00
我已经尝试写了方法来做到这一点,它部分工作,但一些未总结的项目仍然存在。
private static List<ModeTime> MergeTime(List<ModeTime> modeTimes)
{
modeTimes = modeTimes.OrderBy(e => e.Date).ToList();
var mergedModeTimes = new List<ModeTime>();
for (var i = 0; i < modeTimes.Count; i++)
{
if (i - 1 != -1)
{
if (modeTimes[i].LineName == modeTimes[i - 1].LineName &&
modeTimes[i].Mode == modeTimes[i - 1].Mode)
{
mergedModeTimes.Add(new ModeTime
{
Date = modeTimes[i - 1].Date,
LineName = modeTimes[i - 1].LineName,
Mode = modeTimes[i - 1].Mode,
Time = modeTimes[i - 1].Time + modeTimes[i].Time
});
i += 2;
}
else
{
mergedModeTimes.Add(modeTimes[i]);
}
}
else
{
mergedModeTimes.Add(modeTimes[i]);
}
}
return mergedModeTimes;
}
我还尝试用do {} while() 包装for 并减少源列表modeTimes 的长度。不幸的是,它会导致循环和内存泄漏(我等到 5GB 内存使用)。
希望有人可以帮助我。我搜索了这个问题,在一些熟悉的情况下人们使用GroupBy。但我不认为它适用于我的情况,我必须用相同的LineName 和Mode 对项目求和,前提是它们一一在列表中。
【问题讨论】:
-
从不、从不、从不增加 for 循环内的索引计数 (i += 2;)。而是使用 while 循环。您应该增加 1 而不是 2,因为 for 循环计数也增加 1,所以您增加 3 而不是 2。
标签: c# list linq ienumerable