Прежде всего, я должен сказать, что провел весь день в поисках ответа, прежде чем разместить этот вопрос здесь. Ближайший ответ, который я получаю, это здесь, но некоторые ответы мне не подошли, а другие слишком сложны для понимания. Позвольте мне четко объяснить, чего я хочу достичь: для простоты давайте представим, что у меня есть список, состоящий из «6» объектов. Я случайным образом выбираю индекс в списке, скажем, myList[index=2]. Затем я хочу, чтобы этот объект находился в конце списка, что означает, что его значение индекса теперь равно 5. Также я хочу переупорядочить нетронутые объекты, чтобы получить тот же размер списка без пустого значения индекса. После всех этих шагов должно получиться так:
На данный момент мой код таков:
public static void Move<T>(this List<T> list, int oldIndex, int newIndex)
{
if ((oldIndex == newIndex) || (0 > oldIndex) || (oldIndex >= list.Count) || (0 > newIndex) ||
(newIndex >= list.Count)) return;
// local variables
var i = 0;
T tmp = list[oldIndex];
for (i = oldIndex+1; i < newIndex; i++)
{
list[i] = list[i - 1];
}
list[newIndex] = tmp;
}
Однако, как вы можете предсказать, это не работает. Debug.DrawLine для игровых объектов в этом списке показывает мне, когда я перемещаю элементы по списку с помощью моего кода, оставляющего мне два объекта: один myList[0] и один myList[5], которые я добавил. Другие линии исчезают после.
Я думаю, вы хотите + 1
вместо - 1
, и oldIndex
вместо oldIndex+1
, и i < newIndex - 1
вместо i < newIndex
. Но это работает только тогда, когда newIndex > oldIndex. если это наоборот, чем код, который у вас есть, будет более точным.
Просто чтобы уточнить, вы хотите создать метод, который извлекает объект по заданному индексу, а затем добавляет его в конец вашего списка? Или извлекает объект по заданному индексу, а затем добавляет его по другому указанному индексу?
@SharpNip это первое. Когда я вызываю этот метод, я всегда даю newIndex (list.Count-1), поэтому он идет в конец моего списка.
Что ж, вы уже сохранили копию из «oldIndex» в переменную «tmp», поэтому я думаю, что вы просто хотите «list.RemoveAt (oldIndex)», а затем «list.Add (tmp)», чтобы добавить его в конец. Может я что-то упускаю...
@Джонни, если твои числа представляют мои объекты, то да. Я хочу взять третий объект и сделать его последним в моем списке, чтобы его индекс был теперь (list.count -1 = 4), в то время как объект 1 имеет индекс 0, объект 2 имеет индекс 1, объект 4 имеет индекс 2, объект 5 имеет индекс 3.
Вы слишком много думаете об этом.
var value = list[index];
list.RemoveAt(index);
list.Add(value);
Я бы просто добавил if (oldIndex >= list.Count) return;
прямо перед этим.
@SharpNip индекс в списке никогда не будет >= list.Count
.. Я думаю, вы упомянули if (index == list.Count - 1) return;
. В других случаях, когда указан неверный индекс, я бы всегда предпочел выдать ошибку/исключение, чтобы правильно отладить, почему был предоставлен даже неправильный индекс, чем скрыть этот факт, просто вернув его;)
Прошу прощения за дублированный пост. Я пробовал это решение раньше, но я не мог заставить его работать. Должно быть, что-то пропустил. Спасибо всем за ответы.
@derHugo, переданный индекс не из «списка», он передается как параметр метода, поэтому нежелательно выполнять какое-либо выполнение, если переданный индекс больше, чем количество элементов в списке. список. Кроме того, if (index == list.Count - 1)
вызовет исключение, если индекс, переданный методу, является последним объектом в списке или выше, и, учитывая исходный код, это не то, что нужно.
@SharpNip Думаю, ты не совсем понял мою мысль. 1. Вы можете вернуться на if (index == list.Count - 1)
, потому что тогда это уже является последний элемент в списке, поэтому делать нечего. 2. Представленный здесь ответ даже не требует этого параметра oldindex
, поскольку ему нужен только один текущий index
элемента, который затем перемещается в конец. 3. Как я объяснил, я бы не просто возвращался в случае недопустимого ввода, а скорее хотел бы, чтобы было выдано исключение/ошибка, чтобы правильно выяснить, что я сделал неправильно, вместо того, чтобы запутывать это, просто возвращаясь без какой-либо обратной связи.
@derHugo Прости. Я был неправ, ты был прав.
Звуки
LinkedList<T>
могут вам помочь... например, у вас есть 1 2 3 4 5, а затем вы получаете 3, поэтому следующий порядок должен быть 1 2 4 5 3?