Arrays neu anordnen

98

Angenommen, ich habe ein Array, das so aussieht:

var playlist = [
    {artist:"Herbie Hancock", title:"Thrust"},
    {artist:"Lalo Schifrin", title:"Shifting Gears"},
    {artist:"Faze-O", title:"Riding High"}
];

Wie kann ich ein Element an eine andere Position verschieben?

Ich möchte zum Beispiel {artist:"Lalo Schifrin", title:"Shifting Gears"}zum Ende gehen.

Ich habe versucht, Spleiß wie folgt zu verwenden:

var tmp = playlist.splice(2,1);
playlist.splice(2,0,tmp);

Aber es funktioniert nicht.

Wurlitzer
quelle
3
Was bedeutet "funktioniert nicht" - löst es einen Fehler aus, ändert es nichts, ändert es Ihr Array auf eine Weise, die Sie nicht beabsichtigt haben? Es sieht für mich vernünftig aus.
Jacob Mattison

Antworten:

220

Die Syntax von Array.splicelautet:

yourArray.splice(index, howmany, element1, /*.....,*/ elementX);

Wo:

  • Index ist die Position in dem Array, aus der Sie Elemente entfernen möchten
  • Wie viele Elemente möchten Sie aus dem Index entfernen ?
  • element1, ..., elementX sind Elemente, die aus dem Positionsindex eingefügt werden sollen .

Dies bedeutet, dass splice()je nach übergebenen Argumenten Elemente entfernt, Elemente hinzugefügt oder Elemente in einem Array ersetzt werden können.

Beachten Sie, dass ein Array der entfernten Elemente zurückgegeben wird.

Etwas Nettes und Generisches wäre:

Array.prototype.move = function (from, to) {
  this.splice(to, 0, this.splice(from, 1)[0]);
};

Dann benutze einfach:

var ar = [1,2,3,4,5];
ar.move(0,3);
alert(ar) // 2,3,4,1,5

Diagramm:

Algorithmusdiagramm

Matt
quelle
17
Dies ist eine gute Antwort, und der Spleiß () innerhalb eines Spleißes () macht den Job gut. Es sollte jedoch beachtet werden, dass das Hinzufügen einer move () -Methode zum Array-Prototyp als "Monkey Patching" bezeichnet wird und normalerweise als schlechte Praxis angesehen wird. stackoverflow.com/questions/5741877/…
Aaron Cicali
20

Wenn Sie die Indizes kennen, können Sie die Elemente mit einer einfachen Funktion wie dieser einfach austauschen:

function swapElement(array, indexA, indexB) {
  var tmp = array[indexA];
  array[indexA] = array[indexB];
  array[indexB] = tmp;
}

swapElement(playlist, 1, 2);
// [{"artist":"Herbie Hancock","title":"Thrust"},
//  {"artist":"Faze-O","title":"Riding High"},
//  {"artist":"Lalo Schifrin","title":"Shifting Gears"}]

Array-Indizes sind nur Eigenschaften des Array-Objekts, sodass Sie seine Werte austauschen können.

CMS
quelle
Danke, @CMS. Wenn ich meine Mittelwerte tausche, möchte ich die Reihenfolge nicht ersetzen ... Wenn ich zum Beispiel das 3. Objekt auf die 1. Position auswähle, möchte ich 1 als 2 und 2 als 3 als 1 tauschen
Peri
13

Hier ist eine unveränderliche Version für diejenigen, die interessiert sind:

function immutableMove(arr, from, to) {
  return arr.reduce((prev, current, idx, self) => {
    if (from === to) {
      prev.push(current);
    }
    if (idx === from) {
      return prev;
    }
    if (from < to) {
      prev.push(current);
    }
    if (idx === to) {
      prev.push(self[from]);
    }
    if (from > to) {
      prev.push(current);
    }
    return prev;
  }, []);
}
chmanie
quelle
Hallo, können Sie mir die Vorteile dieser Funktion gegenüber der obigen Antwort erklären?
Xogno
1
Diese Lösung ändert das ursprüngliche Element nicht, gibt jedoch ein neues Array zurück, wobei der Eintrag verschoben wird.
Chmanie
7

Ändern Sie 2 als den ersten Parameter im Spleißaufruf, wenn Sie das Element entfernen:

var tmp = playlist.splice(1, 1);
playlist.splice(2, 0, tmp[0]);
Trevor
quelle
1
es sollte playlist.splice sein (2,0, tmp [0]); Richtig?
Crisboot
7

Mit ES6 können Sie so etwas tun:

const swapPositions = (array, a ,b) => {
  [array[a], array[b]] = [array[b], array[a]]
}

let array = [1,2,3,4,5];
swapPositions(array,0,1);

/// => [2, 1, 3, 4, 5]
arthurDent
quelle
1
Dies vertauscht die Positionen der beiden Elemente. Frage ist zur Nachbestellung.
BY
5

Sie können jederzeit die Sortiermethode verwenden, wenn Sie nicht wissen, wo sich der Datensatz derzeit befindet:

playlist.sort(function (a, b) {
    return a.artist == "Lalo Schifrin" 
               ? 1    // Move it down the list
               : 0;   // Keep it the same
});
Andy E.
quelle
Was ist mitreturn +(a.artist == "Lalo Schifrin")
Funkodebat
2
@Funko Sie könnten das tun, wenn Sie Kürze gegenüber Ausführlichkeit bevorzugen.
Andy E
2

EDIT: Bitte überprüfen Sie Andys Antwort da seine Antwort zuerst kam und dies nur eine Erweiterung seiner ist

Ich weiß, dass dies eine alte Frage ist, aber ich denke, es lohnt sich, sie aufzunehmen Array.prototype.sort().

Hier ist ein Beispiel von MDN zusammen mit dem Link

var numbers = [4, 2, 5, 1, 3];
numbers.sort(function(a, b) {
  return a - b;
});
console.log(numbers);

// [1, 2, 3, 4, 5]

Zum Glück funktioniert es nicht nur mit Zahlen:

arr.sort([compareFunction])

compareFunction

Gibt eine Funktion an, die die Sortierreihenfolge definiert. Wenn nicht angegeben, wird das Array nach dem Unicode-Codepunktwert jedes Zeichens gemäß der Zeichenfolgenkonvertierung jedes Elements sortiert.

Mir ist aufgefallen, dass Sie sie mit Vornamen bestellen:

let playlist = [
    {artist:"Herbie Hancock", title:"Thrust"},
    {artist:"Lalo Schifrin", title:"Shifting Gears"},
    {artist:"Faze-O", title:"Riding High"}
];

// sort by name
playlist.sort((a, b) => {
  if(a.artist < b.artist) { return -1; }
  if(a.artist > b.artist) { return  1; }

  // else names must be equal
  return 0;
});

Beachten Sie, dass Sie, wenn Sie sie nach Nachnamen bestellen möchten, entweder einen Schlüssel für beide first_name& haben müssenlast_name oder eine regex Magie tun, was ich nicht tun kann , XD

Hoffentlich hilft das :)

Jaacko Torus
quelle
Dies sollte eine Bearbeitung oder ein Kommentar zu dieser Antwort sein .
Jared Smith
@ JaredSmith Ups! Ich habe seine Antwort nicht gesehen. Ich habe nicht genug Punkte oder was auch immer, um seine Frage zu bearbeiten, und ich denke nicht, dass all diese Informationen in einem Kommentar hinzugefügt werden sollten. Also, bis jemand seine Frage bearbeitet, füge ich einfach hinzu, dass dies eine Erweiterung der Antwort von Andy E ist (wie ich es hätte tun sollen).
Jaacko Torus
Ich denke, es ist jetzt in Ordnung :)
Jared Smith
1

Versuche dies:

playlist = playlist.concat(playlist.splice(1, 1));
JamieJag
quelle
1

Wenn Sie immer nur ein Element von einer beliebigen Position an das Ende des Arrays verschieben möchten, sollte dies funktionieren:

function toEnd(list, position) {
    list.push(list.splice(position, 1));
    return list;
}

Wenn Sie mehrere Elemente von einer beliebigen Position zum Ende verschieben möchten, haben Sie folgende Möglichkeiten:

function toEnd(list, from, count) {
    list.push.apply(list, list.splice(from, count));
    return list;
}

Wenn Sie mehrere Elemente von einer beliebigen Position an eine beliebige Position verschieben möchten, versuchen Sie Folgendes:

function move(list, from, count, to) {
    var args = [from > to ? to : to - count, 0];
    args.push.apply(args, list.splice(from, count));
    list.splice.apply(list, args);

    return list;
}
Okonomiyaki3000
quelle
0

Als einfache veränderbare Lösung können Sie Spleiß zweimal hintereinander aufrufen:

playlist.splice(playlist.length - 1, 1, ...playlist.splice(INDEX_TO_MOVE, 1))

Andererseits könnte eine einfache unveränderliche Lösung Slice verwenden, da diese Methode eine Kopie eines Abschnitts aus dem ursprünglichen Array zurückgibt, ohne ihn zu ändern:

const copy = [...playlist.slice(0, INDEX_TO_MOVE - 1), ...playlist.slice(INDEX_TO_MOVE), ...playlist.slice(INDEX_TO_MOVE - 1, INDEX_TO_MOVE)]
David
quelle
-2

Ordnen Sie seine Arbeit auf diese Weise neu

 var tmpOrder = playlist[oldIndex];
    playlist.splice(oldIndex, 1);
    playlist.splice(newIndex, 0, tmpOrder);

Ich hoffe das wird funktionieren

Peri
quelle
1
Was fügt dies den vorhandenen Antworten hinzu?
Jared Smith