Ich habe also eine generische Liste und einen oldIndex
und einen newIndex
Wert.
Ich möchte den Gegenstand verschieben oldIndex
, um newIndex
... so einfach wie möglich.
Irgendwelche Vorschläge?
Hinweis
Der Gegenstand sollte zwischen den Gegenständen am (newIndex - 1)
und newIndex
vor dem Entfernen liegen.
newIndex--
führt nicht zu dem Verhalten, von dem Sie sagten, dass Sie es wollten.ObservableCollection
und ist kein GenerikumList<T>
, aber es ist trivial, einfach die Methodenaufrufe auszutauschen, um das gleiche Ergebnis zu erzielen.[newIndex - 1]
und[newIndex]
ist nicht invertierbar.Move(1, 3); Move(3, 1);
bringt die Liste nicht in den Ausgangszustand zurück. Mittlerweile gibt es ein anderes Verhalten zur Verfügung gestellt inObservableCollection
und in dieser Antwort erwähnt , das ist umkehrbar .Antworten:
Ich weiß, dass Sie "generische Liste" gesagt haben, aber Sie haben nicht angegeben, dass Sie die List (T) -Klasse verwenden müssen. Hier ist ein Schuss auf etwas anderes.
Die ObservableCollection (T) -Klasse verfügt über eine Move-Methode , die genau das tut, was Sie wollen.
Darunter ist es grundsätzlich so implementiert.
Wie Sie sehen können, ist die von anderen vorgeschlagene Swap-Methode im Wesentlichen das, was die ObservableCollection in ihrer eigenen Move-Methode tut.
UPDATE 30.12.2015: Sie können den Quellcode für die Methoden Move und MoveItem in corefx jetzt selbst anzeigen, ohne Reflector / ILSpy zu verwenden, da .NET Open Source ist.
quelle
quelle
newIndex
bricht meinen Test tatsächlich ab (siehe meine Antwort unten).lock
Anweisung enthalten sein.Ich weiß, dass diese Frage alt ist, aber ich habe DIESE Antwort des Javascript-Codes an C # angepasst . Ich hoffe es hilft
quelle
List <T> .Remove () und List <T> .RemoveAt () geben das zu entfernende Element nicht zurück.
Deshalb müssen Sie dies verwenden:
quelle
Legen Sie das Element derzeit auf
oldIndex
seinen annewIndex
und dann die ursprüngliche Instanz entfernen.Sie müssen berücksichtigen, dass sich der Index des Elements, das Sie entfernen möchten, aufgrund des Einfügens ändern kann.
quelle
Ich habe eine Erweiterungsmethode zum Verschieben von Elementen in einer Liste erstellt.
Ein Index sollte sich nicht verschieben, wenn wir ein vorhandenes Element verschieben, da wir ein Element an eine vorhandene Indexposition in der Liste verschieben.
Der Randfall, auf den sich @Oliver unten bezieht (Verschieben eines Elements an das Ende der Liste), würde tatsächlich dazu führen, dass die Tests fehlschlagen. Dies ist jedoch beabsichtigt. Um ein neues Element am Ende der Liste einzufügen, rufen wir einfach an
List<T>.Add
.list.Move(predicate, list.Count)
sollte fehlschlagen, da diese Indexposition vor dem Verschieben nicht vorhanden ist.Auf jeden Fall habe ich zwei zusätzliche Erweiterungsmethoden erstellt,
MoveToEnd
undMoveToBeginning
die Quelle von denen gefunden werden kann hier .quelle
Ensure.Argument
definiert?List<T>
Sie anrufenInsert(list.Count, element)
, um etwas am Ende der Liste zu platzieren. SieWhen_new_index_is_higher
sollten also anrufen,list.Move(x => x == 3, 5)
was tatsächlich fehlschlägt.List<T>
würde ich einfach anrufen.Add
, um ein neues Element am Ende einer Liste einzufügen . Beim Verschieben einzelner Elemente wird die ursprüngliche Größe des Index niemals erhöht, da nur ein einzelnes Element entfernt und erneut eingefügt wird. Wenn Sie auf den Link in meiner Antwort klicken, finden Sie den Code fürEnsure.Argument
.Ich würde entweder erwarten:
... oder:
... würde den Trick machen, aber ich habe kein VS auf diesem Computer, um es zu überprüfen.
quelle
newIndex
wenn es danach istoldIndex
.Einfachster Weg:
BEARBEITEN
Die Frage ist nicht sehr klar ... Da es uns egal ist, wohin der
list[newIndex]
Artikel geht, ist meiner Meinung nach der einfachste Weg, dies zu tun (mit oder ohne Erweiterungsmethode):Diese Lösung ist die schnellste, da keine Listen eingefügt / entfernt werden müssen.
quelle
Ist einfacher Jungs machen das einfach
Machen Sie dasselbe mit MoveDown, aber ändern Sie das if für "if (ind! = Concepts.Count ())" und das Concepts.Insert (ind + 1, item.ToString ());
quelle
So habe ich eine Erweiterungsmethode für Verschiebungselemente implementiert. Es handhabt das Bewegen vor / nach und bis zum Äußersten für Elemente ziemlich gut.
quelle