776 Stimmen

Verschieben eines Array-Elements von einer Array-Position zu einer anderen

Ich habe eine harte Zeit herauszufinden, wie man ein Element eines Arrays zu bewegen. Zum Beispiel, gegeben die folgenden:

var array = [ 'a', 'b', 'c', 'd', 'e'];

Wie kann ich eine Funktion schreiben, um das Element zu verschieben 'd' links von 'b' ?

O 'a' rechts von 'c' ?

Nach dem Verschieben der Elemente sollten die Indizes der übrigen Elemente aktualisiert werden. Die resultierende Anordnung wäre:

array = ['a', 'd', 'b', 'c', 'e']

Das scheint ziemlich einfach zu sein, aber ich kann es nicht begreifen.

0 Stimmen

ES6 verwenden const changeValuePosition = (arr, init, target) => {[arr[init],arr[target]] = [arr[target],arr[init]]; return arr}

5 Stimmen

Das vertauscht einfach die Elemente bei init y target .

0 Stimmen

@user4945014 Es geht nicht nur um den Tausch. Wenn eine Vertauschung stattfindet, würde der OP array = ['a', 'd', 'c', 'b', 'e'] erhalten, was bedeuten würde, dass 'c' und 'b' in der falschen Reihenfolge wären. Ein Insert und Shift, wie er es sucht, hält 'b' und 'c' in der gleichen Reihenfolge.

26voto

Elie Teyssedou Punkte 691

Hier ist mein ES6-Einzelplatzlösung mit einem optionalen Parameter on .

if (typeof Array.prototype.move === "undefined") {
  Array.prototype.move = function(from, to, on = 1) {
    this.splice(to, 0, ...this.splice(from, on))
  }
}

Anpassung des ersten Lösungsvorschlags von digiguru

Der Parameter on ist die Anzahl der Elemente, die mit from Sie umziehen möchten.

Hier ist eine verkettbare Variante davon:

if (typeof Array.prototype.move === "undefined") {
  Array.prototype.move = function(from, to, on = 1) {
    return this.splice(to, 0, ...this.splice(from, on)), this
  }
}

[3, 4, 5, 1, 2].move(3, 0, 2) // => [1, 2, 3, 4, 5]

Wenn Sie die Verschmutzung durch Prototypen vermeiden möchten, finden Sie hier eine eigenständige Funktion:

function move(array, from, to, on = 1) {
  return array.splice(to, 0, ...array.splice(from, on)), array
}

move([3, 4, 5, 1, 2], 3, 0, 2) // => [1, 2, 3, 4, 5]

Und schließlich eine reine Funktion, die das ursprüngliche Array nicht verändert:

function moved(array, from, to, on = 1) {
  return array = array.slice(), array.splice(to, 0, ...array.splice(from, on)), array
}

Dies sollte im Grunde jede Variante abdecken, die in jeder anderen Antwort vorkommt.

21voto

Anurag Punkte 136648

Von @Reid stammt die Idee, etwas an die Stelle des zu verschiebenden Elements zu setzen, um die Größe des Arrays konstant zu halten. Das vereinfacht die Berechnungen. Außerdem hat das Verschieben eines leeren Objekts den zusätzlichen Vorteil, dass man später eindeutig nach ihm suchen kann. Das funktioniert, weil zwei Objekte nicht gleich sind, solange sie sich nicht auf dasselbe Objekt beziehen.

({}) == ({}); // false

Hier ist also die Funktion, die das Quell-Array und die Quell- und Zielindizes aufnimmt. Sie können sie bei Bedarf zum Array.prototype hinzufügen.

function moveObjectAtIndex(array, sourceIndex, destIndex) {
    var placeholder = {};
    // remove the object from its initial position and
    // plant the placeholder object in its place to
    // keep the array length constant
    var objectToMove = array.splice(sourceIndex, 1, placeholder)[0];
    // place the object in the desired position
    array.splice(destIndex, 0, objectToMove);
    // take out the temporary object
    array.splice(array.indexOf(placeholder), 1);
}

16voto

Andre Pena Punkte 52140

Dies basiert auf der Lösung von @Reid. Außer:

  • Ich ändere nicht die Array Prototyp.
  • Das Verschieben eines Objekts außerhalb der Grenzen nach rechts führt nicht zu undefined Elemente, wird das Element einfach an die äußerste rechte Position verschoben.

Funktion:

function move(array, oldIndex, newIndex) {
    if (newIndex >= array.length) {
        newIndex = array.length - 1;
    }
    array.splice(newIndex, 0, array.splice(oldIndex, 1)[0]);
    return array;
}

Einheitstests:

describe('ArrayHelper', function () {
    it('Move right', function () {
        let array = [1, 2, 3];
        arrayHelper.move(array, 0, 1);
        assert.equal(array[0], 2);
        assert.equal(array[1], 1);
        assert.equal(array[2], 3);
    })
    it('Move left', function () {
        let array = [1, 2, 3];
        arrayHelper.move(array, 1, 0);
        assert.equal(array[0], 2);
        assert.equal(array[1], 1);
        assert.equal(array[2], 3);
    });
    it('Move out of bounds to the left', function () {
        let array = [1, 2, 3];
        arrayHelper.move(array, 1, -2);
        assert.equal(array[0], 2);
        assert.equal(array[1], 1);
        assert.equal(array[2], 3);
    });
    it('Move out of bounds to the right', function () {
        let array = [1, 2, 3];
        arrayHelper.move(array, 1, 4);
        assert.equal(array[0], 1);
        assert.equal(array[1], 3);
        assert.equal(array[2], 2);
    });
});

10voto

Andrea Punkte 99

Sie können einige grundlegende Berechnungen durchführen und eine universelle Funktion zum Verschieben von Array-Elementen von einer Position zur anderen erstellen.

Bei JavaScript sieht das so aus:

function magicFunction (targetArray, indexFrom, indexTo) { 

    targetElement = targetArray[indexFrom]; 
    magicIncrement = (indexTo - indexFrom) / Math.abs (indexTo - indexFrom); 

    for (Element = indexFrom; Element != indexTo; Element += magicIncrement){ 
        targetArray[Element] = targetArray[Element + magicIncrement]; 
    } 

    targetArray[indexTo] = targetElement; 

}

Eine ausführliche Erklärung finden Sie unter "Moving array elements" bei "Gloommatter".

https://web.archive.org/web/20121105042534/http://www.gloommatter.com:80/DDesign/programming/moving-any-array-elements-universal-function.html

9voto

Ich habe eine unveränderliche ECMAScript 6 Lösung auf der Grundlage von @Merc Hier ist die Antwort:

const moveItemInArrayFromIndexToIndex = (array, fromIndex, toIndex) => {
  if (fromIndex === toIndex) return array;

  const newArray = [...array];

  const target = newArray[fromIndex];
  const inc = toIndex < fromIndex ? -1 : 1;

  for (let i = fromIndex; i !== toIndex; i += inc) {
    newArray[i] = newArray[i + inc];
  }

  newArray[toIndex] = target;

  return newArray;
};

Die Variablennamen können gekürzt werden, verwenden Sie einfach lange Namen, damit der Code sich selbst erklären kann.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X