我正在尝试将包含Date的列表AAA与一系列日期进行比较。我想查看列表中是否存在任何日期范围。如果日期存在,我将列表项复制到另一个列表BBB,否则我将空值添加到列表BBB。
我遇到的问题是,根据我的实际代码,我不知道如何不通过while循环的错误语句,直到它到达比较结束。
使用下面的代码,它会在while循环中传递true和false,这会伪造所需的结果。我得到的结果是每次出现的时间都是假的。简而言之,我们可以说列表包含日期为6/5/2010,日期范围为2010年5月5日至2010年7月5日。所以我会在真正的部分创建一个项目,而在ITAL中创建一个错误的部分,这是错误的。存在的日期可以是真实的也可以是错误的。不是两个,所以我创建了两个项目!
如何才能取得正确的结果?任何其他方法或建议请。
我的代码如下:
DateTime StartDate;
DateTime EndDate;
Datetime tempDate = StartDate;
List<DateTime> dateToEvaluate;
bool TimeIsPresent = false;
foreach (var tempItem in TaskList)
{
while (EndDate.AddDays(1) != tempDate)
{
if (tempItem.Date[0] == tempDate)
{
TimeIsPresent = True;
break;
}
else
{
if (TimeIsPresent == False)
{
if (!(tempDate.DayOfWeek == DayOfWeek.Sunday)
{
dateToEvaluate = new List<DateTime>();
dateToEvaluate.Add(tempDate);
tempTask.Add(new GroupedTask { ID = null,
TaskID = null,
Date = dateToEvaluate });
}
}
}
tempDate = tempDate.AddDays(1);
}
if (TimeIsPresent == True)
{
tempTask.Add(new GroupedTask { ID = tempItem.ID,
TaskID = tempItem.TaskID,
Date = tempItem.Date });
TimeIsPresent = false;
}
}
让我举个例子。我的日期范围如下:8月8日星期一至8月14日星期日。 现在我的任务列表如下:item1:Date 9Aug,item2:Date 11Aug。
所以我的tempTask必须如下: item1:Date 8月8日,taskID:null,ID:null, item2:Date 8 Aug,taskID:678,ID:7, item3:日期10Aug,taskID:null,ID:null, item4:Date11 Aug,taskID:890,ID:34, item5:Date 8月12日,taskID:null,ID:null, item6:Date 8 Aug,taskID:null,ID:null
第二个例子:
我的日期范围如下:8月8日星期一至8月14日星期日。 现在我的任务列表如下:item1:Date 9Aug,item2:Date 11Aug,item3:Date 14Aug
所以我的tempTask必须如下: item1:Date 8月8日,taskID:null,ID:null, item2:Date 8 Aug,taskID:678,ID:7, item3:日期10Aug,taskID:null,ID:null, item4:Date11 Aug,taskID:890,ID:34, item5:Date 8月12日,taskID:null,ID:null, item6:Date 8 Aug,taskID:null,ID:null, item4:Date14 Aug,taskID:894,ID:74,
答案 0 :(得分:1)
我认为你制造的东西比实际上更难。据我了解,您正在使用TaskList
中的每个项目,并查看日期是否属于某个范围。如果是,则将其添加到另一个列表并转到下一个项目,否则将空白条目添加到另一个列表并继续检查。
如果我的理解是正确的,请尝试:
根据OP的评论编辑
代码现在遍历TaskList
中每个项目的整个范围,并添加一个带有日期的空对象或日期的相应任务。
无需使用bool
来确定此方案中是否存在日期。
// Note that you'll have to assign values to StartDate and EndDate, otherwise you'll get
// a Null Reference Exception
DateTime StartDate;
DateTime EndDate;
Datetime tempDate = StartDate;
List<DateTime> dateToEvaluate;
foreach (var tempItem in TaskList)
{
// Reset tempDate to the starting date before each loop
tempDate = StartDate;
while (EndDate.AddDays(1) != tempDate)
{
if (tempDate.DayOfWeek != DayOfWeek.Sunday)
{
if (tempItem.Date[0] == tempDate)
{
tempTask.Add(new GroupedTask { ID = tempItem.ID,
TaskID = tempItem.TaskID,
Date = tempItem.Date });
}
else
{
dateToEvaluate = new List<DateTime>();
dateToEvaluate.Add(tempDate);
tempTask.Add(new GroupedTask { ID = null,
TaskID = null,
Date = dateToEvaluate });
}
}
tempDate = tempDate.AddDays(1);
}
}
已编辑以添加
假设2周的范围,7/1从星期一开始到7/14。假设有两个任务 - 任务1的日期为7/3,任务2的日期为7/12。我期待tempTask中的以下内容:
26个元素(两个任务项目各13个日期),所有元素都有一个空ID,除了两个任务各一个。
您真的想要一个没有重复的综合列表吗?即,在我的例子中,将有13个元素,2个将具有非空ID?如果两个或多个任务具有相同的日期会发生什么?
我确实发现了一个错误,因为我没有在每个循环之前将tempDate重置为开始。
编辑基于新的理解
好的,所以你试图获得第二个列表,其中包含给定范围内的所有日期,GroupedTask
对象将是该日期的现有GroupedTask
,或者为null如果没有匹配,则GroupedTask
为该日期。
我建议你看看Enigmativity的答案,因为这可能是一个更优雅的解决方案(我没有详细研究过),但这是另一种方法。最大的变化是我翻转了while循环和foreach循环。
// Note that you'll have to assign values to StartDate and EndDate, otherwise you'll get
// a Null Reference Exception
DateTime StartDate;
DateTime EndDate;
// Declare an instance of GroupedTask for use in the while loop
GroupedTask newTask;
Datetime tempDate = StartDate;
// Loop through the entire range of dates
while (EndDate.AddDays(1) != tempDate)
{
// You included Sundays in your example, but had earlier indicated they
// weren't needed. If you do want Sundays, you can remove this outer if
// block
if (tempDate.DayOfWeek != DayOfWeek.Sunday)
{
// Create a "null" GroupedTask object
// The Date property in GroupedTask appears to be a List<DateTime>,
// so I chose to initialize it along with the other properties.
newTask = new GroupedTask() { ID = null,
TaskID = null,
Date = new List<DateTime>() { tempDate }};
// For each date in the range, check to see if there are any tasks in the TaskList
foreach (var tempItem in TaskList)
{
// If the current item's date matches the current date in the range,
// update the newTask object with the current item's values.
// NOTE: If more than one item has the current date, the last one in
// will win as this code is written.
if (tempItem.Date[0] == tempDate)
{
newTask.ID = tempItem.ID;
newTask.TaskID = tempItem.TaskID;
newTask.Date = tempItem.Date;
}
}
// Add the newTask object to the second list
tempTask.Add(newTask);
}
}
答案 1 :(得分:0)
我不确定 EndDate , tempDate 以及您示例中的其他内容。但是,如果您尝试遍历DateRange并检查特定日期的存在,那么您可以考虑以下示例:
static void yourFunction()
{
//
//Some Stuffs
//
foreach (var tempItem in TaskList)
{
if (DateRange.Contains(tempItem.Date[0]))
{
//Do Task
}
else
{
//Do Task
}
}
//
//Some Stuffs
//
}
public static IEnumerable<DateTime> DateRange
{
get
{
for (DateTime day = startDate; day < EndDate; day = day.AddDays(1))
{
yield return day;
}
}
}
在一个属性上封装一系列日期是 Jon Skeet 的想法,我从他的书C# in Depth
中了解到它
答案 2 :(得分:0)
我发现你的代码有点混乱,但如果我理解你的意图,那么我有一个使用LINQ的解决方案。我的方法可能有点令人困惑,但我很乐意帮助你完成它。
我的理解是,您有一系列日期要创建GroupedTask
个对象的匹配列表,您将在每个匹配日期从现有TaskList
中获取对象范围或如果没有匹配则创建“虚拟”实例。
我假设您已定义StartDate
变量以及您在问题中使用的EndDate
变量。
我的解决方案(我已经测试过)看起来像这样:
var query =
from d in dates
from t in getTasksForDate(d)
where (t.ID != null) || (d.DayOfWeek != DayOfWeek.Sunday)
select t;
tempTask.AddRange(query);
暂时忽略需要定义的两个部分(dates
&amp; getTasksForDate
),查询的工作方式是从开始到结束运行每个日期并选择该日期的任务(如果日期不存在,则来自TaskList
或“虚拟”任务)然后过滤掉星期日的任何“虚拟”任务。然后将任务添加到tempTask
列表中。
现在找到缺失的部分。
要获取dates
列表,请执行以下操作:
var days = EndDate.Date.Subtract(StartDate.Date).Days + 1;
var dates =
Enumerable
.Range(1 - days, days)
.Select(d => EndDate.AddDays(d));
只要StartDate
在EndDate
之前或之前,您就会有一个日期列表,从StartDate
开始到EndDate
结束。
getTasksForDate
是比较棘手的部分。
您需要先将TaskList
列表转换为查找函数,将任何日期转换为该日期的GroupedTask
个对象列表。使用LINQ很容易:
var lookup = TaskList.ToLookup(x => x.Date[0].Date, x => new GroupedTask()
{
ID = x.ID,
TaskID = x.TaskID,
Date = x.Date,
});
接下来,您需要创建getTasksForDate
函数,该函数将获取日期并返回日期查找中的GroupedTask
列表或单个“虚拟”GroupedTask
对象这个日期没有任务。
Func<DateTime, IEnumerable<GroupedTask>> getTasksForDate = d =>
{
return lookup[d].DefaultIfEmpty(new GroupedTask()
{
ID = null,
TaskID = null,
Date = new List<DateTime>() { d, },
});
};
就是这样。
如果您想根据StartDate
的实际值定义EndDate
和/或TaskList
,可以使用以下代码:
var StartDate = TaskList.Select(t => t.Date[0].Date).Min();
var EndDate = TaskList.Select(t => t.Date[0].Date).Max();
我在大多数.Date
引用之后使用了DateTime
来确保该日期没有时间组件。
如果你想进一步解释,请大声说出来。
答案 3 :(得分:0)
如果我明白你要做什么,我会改变你这样做的方式。首先,我会发现你的范围内的所有日期都有一个或多个相关的任务(并将它们放在一个字典中,以便能够让他们知道日期),然后我会创建tempTask。像这样:
DateTime StartDate;
DateTime EndDate;
DateTime tempDate = StartDate;
List<DateTime> dateToEvaluate;
Dictionary<DateTime, List<Task>> dateTaskDict = new Dictionary<DateTime, List<Task>>();
bool TimeIsPresent = false;
foreach (Task tempItem in TaskList)
{
while (EndDate.AddDays(1) != tempDate)
{
if (tempItem.Date[0] == tempDate)
{
List<Task> tasksForDate;
if (!dateTaskDict.TryGetValue(tempDate, out tasksForDate))
{
tasksForDate = new List<Task>();
dateTaskDict[tempDate] = tasksForDate;
}
tasksForDate.Add(tempItem);
break;
}
tempDate = tempDate.AddDays(1);
}
}
tempDate = StartDate;
while (EndDate.AddDays(1) != tempDate)
{
List<Task> tasks;
if (dateTaskDict.TryGetValue(tempDate, out tasks))
{
foreach (Task aTask in tasks)
tempTask.Add(new GroupedTask { ID = aTask.ID,
TaskID = aTask.TaskID,
Date = tempDate });
}
else
{
if (tempDate.DayOfWeek != DayOfWeek.Sunday)
{
tempTask.Add(new GroupedTask { ID = null
TaskID = null,
Date = tempDate });
}
}
}