public static List<PreviewSchedule> BuildPreviewSchedule(Chatham.Business.Objects.Transaction transaction)
{
List<PreviewSchedule> items = new List<PreviewSchedule>();
List<ScheduleItem> scheduleItems = new List<ScheduleItem>(transaction.ScheduleCollection.FindAll(row => row.IsDeleted == false));
bool allFromDateFilledIn = !scheduleItems.Exists(item => !item.FromDate.HasValue);
bool allFloatingFromDateFilledIn = !scheduleItems.Exists(item => !item.FloatingFromDate.HasValue);
scheduleItems.Sort((a, b) => a.FromDate.GetValueOrDefault().CompareTo(b.FromDate.GetValueOrDefault()));
scheduleItems.Sort((a, b) => SortIt(a, b, allFromDateFilledIn, allFloatingFromDateFilledIn));
for (int i = 0; i < scheduleItems.Count; i++)
{
items.Add(new PreviewSchedule
{
Drop = i == 0 ? "$0.00" :
((scheduleItems[i - 1].PrincipalNotionalAmount - scheduleItems[i].PrincipalNotionalAmount)).Value.ToString(Format.CurrencyCentsIncludedFormatStringDollarSign),
EndDate = GetDateOrNull(scheduleItems[i].ToDate),
StartDate = GetDateOrNull(scheduleItems[i].FromDate),
Notional = scheduleItems[i].PrincipalNotionalAmount.Value.ToString(Format.CurrencyCentsIncludedFormatStringDollarSign),
FloatingEndDate = GetDateOrNull(scheduleItems[i].FloatingToDate),
FloatingStartDate = GetDateOrNull(scheduleItems[i].FloatingFromDate)
});
}
return items;
}
以下是我们调用的方法,将我们的日程安排返回到mvc应用程序的前端。现在,这个列表每次都以相同的方式混合特定模型的最后两行。看看图片:
表的最后两行,你可以明显地看到最后两行被切换,因为日期不会相互跟随。这种方法正在吐出那些混淆的日期,我认为这是排序的问题。你们中的任何人都可以看到排序会导致这种情况吗?
提前致谢。
编辑:
SortIt()代码:
private static int SortIt(
Chatham.Business.Objects.ScheduleItem a,
Chatham.Business.Objects.ScheduleItem b,
bool allFromDateFilledIn,
bool allFloatingFromDateFilledIn)
{
return SortIt(a.FromDate, a.FloatingFromDate, b.FromDate, b.FloatingFromDate, allFromDateFilledIn, allFloatingFromDateFilledIn);
}
private static int SortIt(DateTime? aFrom,
DateTime? aFloatingFrom,
DateTime? bFrom,
DateTime? bFloatingFrom,
bool allFromDateFilledIn,
bool allFloatingFromDateFilledIn)
{
DateTime? a = null;
DateTime? b = null;
if (allFromDateFilledIn == false && allFloatingFromDateFilledIn == false)
{
a = aFrom ?? aFloatingFrom;
b = bFrom ?? bFloatingFrom;
}
else
{
a = allFromDateFilledIn ? aFrom : aFloatingFrom;
b = allFromDateFilledIn ? bFrom : bFloatingFrom;
}
if (a.HasValue && b.HasValue)
return a.Value.CompareTo(b.Value);
return 0;
}
答案 0 :(得分:2)
我注意到倒数第二行是唯一一个填写了所有四个日期的行。我还注意到2013年10月1日是在2013年11月1日之前。我强烈怀疑这些日期是一起比较的。但是,如果不知道SortIt
方法的样子,我无法完全诊断或纠正问题。无论如何,这可能是你问题的根源,所以我会把你的努力集中在那里。
考虑填写所有四个日期后会发生什么,并弄清楚如何处理这种情况。
现在您已添加了SortIt
代码,请查看您的allFromDateFilledIn
和allFloatingFromDateFilledIn
标记。对于您的示例数据,这两个都总是错误的,因为From和FloatingFrom列在某处包含至少一个空单元格。因此,您的SortIt
方法总是会对此进行评估:
a = aFrom ?? aFloatingFrom;
b = bFrom ?? bFloatingFrom;
...这意味着将来自不同列的值进行比较。这也意味着当From和FloatingFrom都存在时,From总是作为比较值获胜。
您可以尝试使用内置if/else
替换上面的内容:
if (aFrom != null && bFrom != null)
{
a = aFrom;
b = bFrom;
}
else if (aFloatingFrom != null && bFloatingFrom != null)
{
a = aFloatingFrom;
b = bFloatingFrom;
}
else
{
a = aFrom ?? aFloatingFrom;
b = bFrom ?? bFloatingFrom;
}
我觉得这种逻辑可能会被减少/美化,但这种方式似乎最容易理解。请注意,From仍然具有比FloatingFrom更高的优先级。
您可能还想考虑布尔标志正在做什么。它们只会在一个或另一个列完全填满时才会发挥作用,在这种情况下,它们会锁定该列作为比较列。这可能是你想要的,也可能是不必要的。您已经确定From优先于FloatingFrom,因此没有理由覆盖该规则,我只是为了保持一致性而遵循它。只是一个想法。
答案 1 :(得分:1)
这里有一个问题:
if (a.HasValue && b.HasValue)
return a.Value.CompareTo(b.Value);
return 0;
如果a
或b
没有值,则可能会返回不一致的返回值。想象一下,如果sort方法使用a=2011/04/24
和b=null
来调用它。它将返回0.后来在同一种类型中,可能会使用a=null
和b=2011/03/24
调用它。在这两种情况下,该方法都将返回0.
当比较方法返回不一致的值时,List.Sort
的行为是未定义的。在这里你有一个案例,给定三个值(我将使用数字,但相同的日期将成立),你不能给出可靠的排序。
a = 5
b = 10
c = null
比较a
和c
会返回0.比较b
和c
也会返回0。一个假定如果a==c
和b==c
,则a==b
。但在这种情况下a < b
。这将导致Sort
无法预测。在这种情况下,某些排序方法会进入无限循环,或者崩溃。