2013-02-14 4 views
2

Я работаю над алгоритмом, который решит проблему, которую я имею, но я нахожу себя немного застрявшим. Вот сценарий:Сортировка и обновление списка объектов на основе изменения переменной

У меня есть объект, который содержит переменную, называемую порядком.

public class Item 
{ 
    public int Order{get; set;}; 

    public int ID{get; set;}; // not incremented can be any value! 
} 

Так у меня есть список из них:

List<Item> list = new List<Item>().OrderBy((o) => o.Order); 

И в любое время стоимость заказа может быть изменено. Итак, если я хочу изменить первое значение порядка элементов, все остальные значения заказа должны соответственно обновиться, чтобы дубликатов не было.

for (int i = 0; i <= list .Count - 1; i++) 
{ 
    if (list [i].ID == inputID) 
    { 
     list [i].Order = inputNewPosition; 
    } 
    else 
    { 
     if (list [i].Order < inputNewPosition) 
     { 
      list [i].Order --; 
     } 
     else 
     { 
      list [i].Order ++; 
     } 
    } 
} 

Это не удается, если я изменил последний порядок предметов, чтобы быть первым, так как это сделает первый порядок предметов равным 0!

Может ли кто-нибудь помочь?

Благодаря

+0

** Поэтому, если я хочу изменить первое значение заказа предметов, все остальные значения заказа должны соответственно обновиться, чтобы дубликатов не было **, разбил мой парсер. может быть, вы хотите перефразировать? – thang

+0

Я ищу разъяснения: из того, что я читаю, я собираю у вас 5 объектов с атрибутами порядка 1,2,3,4,5, и вы хотите иметь возможность изменить объект с помощью Order = 5 на что-то вроде order = 3 и измените 3-> 4 и измените 4-> 5, чтобы освободить место для него. Я на правильном пути? – deepee1

ответ

3

Давайте посмотрим на четыре ситуации для элемента в списке (как мы перебираем их). Если (для терпения) мы берем old как старую позицию позиции, а new - это новая позиция, у нас есть следующие случаи для элемента в вашем списке (выведите их на бумаге, чтобы это стало ясно).

  1. текущий элемент является один для перемещения: переместить его непосредственно
  2. порядок текущего элемента является < new и < old: не перемещайте его
  3. порядок текущего элемента является ≥ new и < old: переместить его вправо
  4. порядок текущего элемента является ≤ new и>old: переместить вправо
  5. порядок текущего элемента является>new и>old: не перемещайте его

Когда мы начинаем перечислять, мы знаем, где элемент будет перемещен в конечном итоге (в new), но мы не знаем, куда он пришел из (old) , Однако по мере того, как мы начинаем наше перечисление на , начинающемся списка, мы знаем на каждом шаге, что он должен быть дальше в списке, пока мы его не увидели! Поэтому мы можем использовать флаг (seen), чтобы сказать, видели ли мы его еще. Таким образом, seen ложных средств < old в то время как истинные средства> = old.

bool seen = false; 
for (int i = 0; i < items.Length; i++) 
{ 
    if (items[i].ID == inputID) 
    { 
     items[i].Order = inputNewPosition; 
     seen = true; 
    } 
} 

Этот флаг говорит нам, является ли текущий элемент> = старый. Так что теперь можно начинать шунтирование по этим знаниям и вышеприведенным правилам. (Так new в приведенном выше обсуждении является inputNewPosition и ли мы до или после того, как old мы представляем нашу seen переменной.)

bool seen; 
for (int i = 0; i < items.Count; i++) 
{ 
    if (items[i].ID == inputID) // case 1 
    { 
     items[i].Order = inputNewPosition; 
     seen = true; 
    } 
    else if (seen) // cases 4 & 5 
    { 
     if (items[i].Order <= inputNewPosition) // case 4 
     { 
      items[i].Order--; // move it left 
     } 
    } 
    else // case 2 & 3 
    { 
     if (items[i].Order >= inputNewPosition) // case 3 
     { 
      items[i].Order++; // move it right 
     }    
    } 
} 

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

+0

Спасибо, чувак за вашу помощь, классный ответ –

0

Ваш вопрос не очень ясен, но для требований, которые, скорее всего, вам лучше всего сделать событие на объекте, содержащем заказ, и, возможно, иметь объект-контейнер, который может его контролировать. Однако я подозреваю, что вы захотите переосмыслить свой алгоритм, если это так, так как кажется очень неудобным способом справиться с проблемой отображения в порядке.

Сказанное, в чем проблема? Если я переключу порядок позиции № 2 на № 5, что должно произойти с №3? Остается ли оно там, где оно есть, или должно быть №6?