Проблема сортировки списка в c # - PullRequest
1 голос
/ 04 апреля 2011
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.Теперь этот список каждый раз одинаково смешивал последние две строки в конкретной модели.Посмотрите на картинку: enter image description here

В последних двух строках таблицы вы можете видеть, что последние две строки поменялись местами, потому что даты не следуют друг за другом.Этот метод выплевывает эти перепутанные даты, и я думаю, что это проблема с сортировкой.Кто-нибудь из вас, ребята, может видеть, откуда такая сортировка?

Спасибо заранее.

Редактировать:

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;
        }

Ответы [ 2 ]

2 голосов
/ 04 апреля 2011

Я замечаю, что вторая-последняя строка является единственной, в которой заполнены все четыре даты. Я также замечаю, что 01 октября 2013 года - до 01 ноября 2013 года. Я сильно подозреваю, что эти даты сравниваются друг с другом. Я не могу полностью диагностировать или исправить проблему, не зная, как выглядит метод SortIt. Несмотря на это, это, вероятно, источник вашей проблемы, поэтому я бы сосредоточил ваши усилия там.

Подумайте, что должно произойти, когда все четыре даты заполнены, и выясните, как обращаться с этим делом.

Edit:

Теперь, когда вы добавили код SortIt, взгляните на флаги allFromDateFilledIn и allFloatingFromDateFilledIn. Оба из них всегда будут ложными с данными вашего примера, потому что оба столбца From и FloatingFrom содержат где-то хотя бы одну нулевую ячейку. Следовательно, ваш SortIt метод всегда будет оценивать это:

a = aFrom ?? aFloatingFrom;
b = bFrom ?? bFloatingFrom;

... что означает сравнение значений из разных столбцов вместе. Это также означает, что при наличии как From, так и FloatingFrom значение сравнения всегда побеждает.

Редактировать 2:

Вы можете попробовать заменить вышеприведенное внутренним 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 голос
/ 04 апреля 2011

Здесь проблема:

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 вести себя непредсказуемо.Некоторые методы сортировки могут зайти в бесконечный цикл в этой ситуации или привести к сбою.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...