Итак, у меня есть общий список, а также oldIndex
и newIndex
значение.
Я хочу переместить элемент в oldIndex
, чтобы newIndex
... как можно проще.
Какие-либо предложения?
Заметка
Предмет должен находиться между предметами до(newIndex - 1)
и newIndex
до его удаления.
newIndex--
не приводит к поведению, которое вы сказали, что вы хотели.ObservableCollection
и не является универсальнымList<T>
, но тривиально просто поменять местами вызовы методов, чтобы получить тот же результат.[newIndex - 1]
и[newIndex]
не является обратимым.Move(1, 3); Move(3, 1);
не возвращает список в исходное состояние. В то же время существует другое поведение предусмотреноObservableCollection
и упоминается в этом ответе , который является обратимым .Ответы:
Я знаю, что вы сказали «универсальный список», но вы не указали, что вам нужно использовать класс List (T), так что здесь вы видите что-то другое.
Класс ObservableCollection (T) имеет метод Move, который делает именно то, что вы хотите.
Под ним в основном реализовано так.
Итак, как вы можете видеть, метод подкачки, предложенный другими, по сути, является тем, что ObservableCollection делает в своем собственном методе Move.
ОБНОВЛЕНИЕ 2015-12-30: Вы можете увидеть исходный код для методов Move и MoveItem в corefx прямо сейчас, не используя Reflector / ILSpy, поскольку .NET является открытым исходным кодом.
источник
источник
newIndex
фактически нарушает мой тест (см. Мой ответ ниже).lock
оператора.Я знаю, что этот вопрос старый, но я адаптировал ЭТОТ ответ кода JavaScript на C #. Надеюсь, поможет
источник
List <T> .Remove () и List <T> .RemoveAt () не возвращают удаляемый элемент.
Поэтому вы должны использовать это:
источник
Вставьте элемент, который в данный момент находится в
oldIndex
точке,newIndex
а затем удалите исходный экземпляр.Вы должны принять во внимание, что индекс элемента, который вы хотите удалить, может измениться из-за вставки.
источник
Я создал метод расширения для перемещения элементов в списке.
Индекс не должен сдвигаться, если мы перемещаем существующий элемент, так как мы перемещаем элемент в существующую позицию индекса в списке.
Крайний случай, на который @Oliver ссылается ниже (перемещение элемента в конец списка), фактически приведет к сбою тестов, но это сделано специально. Чтобы вставить новый элемент в конец списка, мы просто позвоним
List<T>.Add
.list.Move(predicate, list.Count)
должен потерпеть неудачу, так как эта позиция индекса не существует до движения.В любом случае, я создал два дополнительных метода расширения,
MoveToEnd
иMoveToBeginning
, источник которого можно найти здесь .источник
Ensure.Argument
определяется?List<T>
вы можете позвонить,Insert(list.Count, element)
чтобы поместить что-то в конец списка. Так что вамWhen_new_index_is_higher
следует позвонить,list.Move(x => x == 3, 5)
который на самом деле не удается.List<T>
я бы просто позвонил,.Add
чтобы вставить новый элемент в конец списка. При перемещении отдельных элементов мы никогда не увеличиваем исходный размер индекса, поскольку удаляем только один элемент и вставляем его заново. Если вы нажмете на ссылку в моем ответе, вы найдете код дляEnsure.Argument
.Я бы ожидал либо:
... или:
... сделал бы уловку, но у меня нет VS на этой машине, чтобы проверить.
источник
newIndex
если это послеoldIndex
.Самый простой способ:
РЕДАКТИРОВАТЬ
Вопрос не очень ясен ... Так как нас не волнует, куда
list[newIndex]
идет элемент, я думаю, что самый простой способ сделать это заключается в следующем (с или без метода расширения):Это решение является самым быстрым, потому что оно не включает в себя вставку / удаление списка.
источник
Есть более простые ребята, просто сделайте это
Сделайте то же самое с MoveDown, но измените if для «if (ind! = Concepts.Count ())» и Concepts.Insert (ind + 1, item.ToString ());
источник
Вот как я реализовал метод расширения элемента move. Он неплохо справляется с перемещением до / после и в крайности для элементов.
источник