Riordino di array


98

Dì, ho un array che assomiglia a questo:

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

Come posso spostare un elemento in un'altra posizione?

Voglio muovermi, ad esempio, {artist:"Lalo Schifrin", title:"Shifting Gears"}fino alla fine.

Ho provato a usare la giunzione, in questo modo:

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

Ma non funziona.


3
Cosa significa "non funziona": genera un errore, non cambia nulla, cambia il tuo array in un modo che non avevi previsto? Mi sembra ragionevole.
Jacob Mattison

Risposte:


220

La sintassi di Array.spliceè:

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

Dove:

  • index è la posizione nell'array da cui vuoi iniziare a rimuovere gli elementi
  • howmany è il numero di elementi che desideri rimuovere da index
  • elemento1, ..., elementX sono elementi che si desidera inserita dalla posizione di indice .

Ciò significa che splice()può essere utilizzato per rimuovere elementi, aggiungere elementi o sostituire elementi in un array, a seconda degli argomenti passati.

Notare che restituisce un array degli elementi rimossi.

Qualcosa di carino e generico sarebbe:

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

Quindi usa:

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

Diagramma:

Diagramma dell'algoritmo


17
Questa è una buona risposta e splice () all'interno di splice () fa bene il lavoro. Va notato, tuttavia, che l'aggiunta di un metodo move () al prototipo di Array è chiamata "Monkey Patching" ed è generalmente considerata una cattiva pratica. stackoverflow.com/questions/5741877/…
Aaron Cicali

20

Se conosci gli indici potresti facilmente scambiare gli elementi, con una semplice funzione come questa:

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"}]

Gli indici array sono solo proprietà dell'oggetto array, quindi puoi scambiarne i valori.


Grazie, @CMS. Se cambio la media non voglio sostituire l'ordine ... Ad esempio, se seleziono il 3 ° oggetto in 1 ° posizione, voglio scambiare 1 come 2 e 2 come 3 come 1
Peri

13

Ecco una versione immutabile per coloro che sono interessati:

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;
  }, []);
}

Ciao, potresti spiegarmi i vantaggi di questa funzione rispetto alla risposta sopra?
Xogno

1
Questa soluzione non modifica l'elemento originale ma restituisce un nuovo array con la voce spostata.
chmanie

7

Modificare 2 in 1 come primo parametro nella chiamata di giunzione quando si rimuove l'elemento:

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

1
dovrebbe essere playlist.splice (2,0, tmp [0]); Destra?
Crisboot

7

Con ES6 puoi fare qualcosa del genere:

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]

1
Questo scambia le posizioni dei due elementi. La domanda è per il riordino.
ENTRO il

5

Puoi sempre usare il metodo di ordinamento, se non sai dove si trova il record al momento:

playlist.sort(function (a, b) {
    return a.artist == "Lalo Schifrin" 
               ? 1    // Move it down the list
               : 0;   // Keep it the same
});

Che direreturn +(a.artist == "Lalo Schifrin")
Funkodebat

2
@ Funko potresti farlo, se preferisci la brevità alla verbosità.
Andy E

2

EDIT: Per favore controlla la risposta di Andy poiché la sua risposta è arrivata prima e questa è solo un'estensione della sua

So che questa è una vecchia domanda, ma penso che valga la pena includerla Array.prototype.sort().

Ecco un esempio da MDN insieme al collegamento

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

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

Fortunatamente non funziona solo con i numeri:

arr.sort([compareFunction])

compareFunction

Specifica una funzione che definisce l'ordinamento. Se omesso, l'array viene ordinato in base al valore del punto di codice Unicode di ciascun carattere, in base alla conversione di stringa di ciascun elemento.

Ho notato che li stai ordinando per nome:

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;
});

nota che se vuoi ordinarli per cognome dovresti avere una chiave per entrambi first_name & last_nameo fare un po 'di magia regex, cosa che non posso fare XD

Spero che aiuti :)


Questa dovrebbe essere una modifica o un commento a questa risposta .
Jared Smith

@JaredSmith Oops! Non ho visto la sua risposta. Non ho abbastanza punti o altro per modificare la sua domanda e non credo che tutte queste informazioni dovrebbero essere aggiunte in un commento. Quindi, fino a quando qualcuno modifica la sua domanda, aggiungerò semplicemente che questa è un'estensione della risposta di Andy E (come avrei dovuto fare).
Jaacko Torus

Penso che ora vada bene :)
Jared Smith

1

Prova questo:

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

1

Se vuoi spostare solo un elemento da una posizione arbitraria alla fine dell'array, dovrebbe funzionare:

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

Se vuoi spostare più elementi da una posizione arbitraria alla fine, puoi fare:

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

Se desideri spostare più elementi da una posizione arbitraria a una posizione arbitraria, prova:

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;
}

0

Come semplice soluzione mutevole puoi chiamare splice due volte di seguito:

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

D'altra parte, una semplice soluzione immutabile potrebbe utilizzare slice poiché questo metodo restituisce una copia di una sezione dall'array originale senza modificarlo:

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

-2

Riordina il suo lavoro in questo modo

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

Spero che funzioni


1
Cosa aggiunge questo alle risposte esistenti?
Jared Smith
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.