Mam więc listę ogólną oraz wartość oldIndex
i newIndex
.
Chcę przenieść element o adres oldIndex
do newIndex
... tak prosto, jak to możliwe.
Jakieś sugestie?
Uwaga
Przedmiot powinien znaleźć się między elementami na miejscu (newIndex - 1)
i newIndex
przed jego usunięciem.
newIndex--
nie skutkuje zachowaniem, o którym mówiłeś, że chciałeś.ObservableCollection
a nie o typieList<T>
, ale trywialne jest po prostu zamiana wywołań metod, aby uzyskać ten sam wynik.[newIndex - 1]
i[newIndex]
nie jest odwracalne.Move(1, 3); Move(3, 1);
nie przywraca listy do stanu początkowego. Tymczasem w tej odpowiedzi podanoObservableCollection
i wspomniano inne zachowanie , które jest odwracalne .Odpowiedzi:
Wiem, że powiedziałeś „lista ogólna”, ale nie określiłeś, że musisz użyć klasy List (T), więc oto próbka na coś innego.
Klasa ObservableCollection (T) ma metodę Move, która robi dokładnie to, co chcesz.
Pod spodem jest zasadniczo zaimplementowany w ten sposób.
Jak widać, metoda zamiany, którą sugerowali inni, jest zasadniczo tym, co robi ObservableCollection w swojej własnej metodzie Move.
AKTUALIZACJA 2015-12-30: Możesz teraz zobaczyć kod źródłowy metod Move i MoveItem w corefx teraz dla siebie bez używania Reflector / ILSpy, ponieważ .NET jest open source.
źródło
źródło
newIndex
faktycznie łamie mój test (zobacz moją odpowiedź poniżej).lock
instrukcji.Wiem, że to pytanie jest stare, ale dostosowałem TĘ odpowiedź kodu javascript do C #. Mam nadzieję, że to pomoże
źródło
List <T> .Remove () i List <T> .RemoveAt () nie zwracają usuwanego elementu.
Dlatego musisz tego użyć:
źródło
Wstaw element, w którym aktualnie
oldIndex
ma być,newIndex
a następnie usuń oryginalne wystąpienie.Musisz wziąć pod uwagę, że indeks elementu, który chcesz usunąć, może ulec zmianie w wyniku wstawienia.
źródło
Stworzyłem metodę rozszerzenia do przenoszenia elementów na liście.
Indeks nie powinien się przesuwać, jeśli przenosimy istniejący element, ponieważ przenosimy element do istniejącej pozycji indeksu na liście.
Przypadek skrajny, do którego odnosi się @Oliver poniżej (przeniesienie elementu na koniec listy) w rzeczywistości spowodowałby niepowodzenie testów, ale jest to zgodne z projektem. Aby wstawić nową pozycję na końcu listy, po prostu zadzwonilibyśmy
List<T>.Add
.list.Move(predicate, list.Count)
powinien nie powieść, ponieważ ta pozycja indeksu nie istnieje przed ruchem.W każdym razie, mam utworzone dwa dodatkowe metody rozszerzenie,
MoveToEnd
iMoveToBeginning
, których źródłem mogą być znalezione tutaj .źródło
Ensure.Argument
zdefiniowane?List<T>
możesz zadzwonić,Insert(list.Count, element)
aby umieścić coś na końcu listy. WięcWhen_new_index_is_higher
powinieneś sprawdzić,list.Move(x => x == 3, 5)
co faktycznie się nie udaje.List<T>
, po prostu zadzwoniłbym,.Add
aby wstawić nowy element na koniec listy. Podczas przenoszenia pojedynczych elementów nigdy nie zwiększamy oryginalnego rozmiaru indeksu, ponieważ usuwamy tylko jeden element i wkładamy go ponownie. Jeśli klikniesz link w mojej odpowiedzi, znajdziesz kodEnsure.Argument
.Spodziewałbym się:
... lub:
... by załatwił sprawę, ale nie mam VS na tym komputerze do sprawdzenia.
źródło
newIndex
jeśli jest pooldIndex
.Najprostszy sposób:
EDYTOWAĆ
Pytanie nie jest zbyt jasne ... Ponieważ nie obchodzi nas, dokąd
list[newIndex]
trafia element, myślę, że najprostszy sposób na zrobienie tego jest następujący (z metodą rozszerzającą lub bez):To rozwiązanie jest najszybsze, ponieważ nie obejmuje wstawiania / usuwania list.
źródło
Czy prostsze faceci po prostu to robią
Zrób to samo z MoveDown, ale zmień if dla "if (ind! = Concepts.Count ())" i Concepts.Insert (ind + 1, item.ToString ());
źródło
W ten sposób zaimplementowałem metodę rozszerzenia elementu Move. Całkiem dobrze radzi sobie z przesuwaniem się przed / po i do skrajności dla elementów.
źródło