Réorganiser les tableaux


98

Dites, j'ai un tableau qui ressemble à ceci:

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

Comment déplacer un élément vers une autre position?

Je veux passer par exemple {artist:"Lalo Schifrin", title:"Shifting Gears"}à la fin.

J'ai essayé d'utiliser l'épissure, comme ceci:

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

Mais ça ne marche pas.


3
Que signifie «ne fonctionne pas» - génère-t-il une erreur, ne change-t-il rien, change-t-il votre tableau d'une manière que vous n'aviez pas prévue? Cela me paraît raisonnable.
Jacob Mattison

Réponses:


220

La syntaxe de Array.spliceest:

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

Où:

  • index est la position dans le tableau à partir de laquelle vous souhaitez commencer à supprimer des éléments
  • combien est le nombre d'éléments que vous souhaitez supprimer de l' index
  • element1, ..., elementX sont des éléments que vous souhaitez insérer à partir de l' index de position .

Cela signifie qu'il splice()peut être utilisé pour supprimer des éléments, ajouter des éléments ou remplacer des éléments dans un tableau, en fonction des arguments que vous passez.

Notez qu'il renvoie un tableau des éléments supprimés.

Quelque chose de bien et de générique serait:

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

Ensuite, utilisez simplement:

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

Diagramme:

Diagramme d'algorithme


17
C'est une bonne réponse, et le splice () dans un splice () fait bien le travail. Il faut cependant noter que l'ajout d'une méthode move () au prototype Array est appelé "Monkey Patching" et est généralement considéré comme une mauvaise pratique. stackoverflow.com/questions/5741877/…
Aaron Cicali

20

Si vous connaissez les index, vous pouvez facilement échanger les éléments, avec une fonction simple comme celle-ci:

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

Les index de tableau ne sont que des propriétés de l'objet tableau, vous pouvez donc échanger ses valeurs.


Merci, @CMS. Si j'échange les moyennes, je ne veux pas remplacer l'ordre ... Par exemple, si je sélectionne le 3ème objet en 1ère position, je veux échanger 1 en 2 et 2 en 3 en 1
Péri

13

Voici une version immuable pour ceux qui sont intéressés:

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

Salut, pourriez-vous m'expliquer les avantages de cette fonction par rapport à la réponse ci-dessus?
Xogno

1
Cette solution ne modifie pas l'élément d'origine mais renvoie un nouveau tableau avec l'entrée déplacée.
chmanie

7

Remplacez 2 par 1 comme premier paramètre dans l'appel d'épissure lors de la suppression de l'élément:

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

1
ce devrait être playlist.splice (2,0, tmp [0]); Droite?
Crisboot

7

Avec ES6, vous pouvez faire quelque chose comme ceci:

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
Cela permute les positions des deux éléments. La question est de réorganiser.
PAR

5

Vous pouvez toujours utiliser la méthode de tri, si vous ne savez pas où se trouve actuellement l'enregistrement:

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

What aboutreturn +(a.artist == "Lalo Schifrin")
Funkodebat

2
@Funko, vous pouvez le faire, si vous préférez la brièveté à la verbosité.
Andy E

2

EDIT: Veuillez consulter la réponse d'Andy car sa réponse est venue en premier et ce n'est qu'une extension de son

Je sais que c'est une vieille question, mais je pense que cela vaut la peine de l'inclure Array.prototype.sort().

Voici un exemple de MDN avec le lien

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

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

Heureusement, cela ne fonctionne pas uniquement avec les nombres:

arr.sort([compareFunction])

compareFunction

Spécifie une fonction qui définit l'ordre de tri. S'il est omis, le tableau est trié en fonction de la valeur du point de code Unicode de chaque caractère, en fonction de la conversion de chaîne de chaque élément.

J'ai remarqué que vous les commandez par prénom:

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

Notez que si vous vouliez les commander par nom de famille que vous devez soit avoir une clé pour les deux first_nameet last_nameou faire de la magie regex, que je ne peux pas XD

J'espère que cela pourra aider :)


Cela devrait être une modification ou un commentaire sur cette réponse .
Jared Smith

@JaredSmith Oups! Je n'ai pas vu sa réponse. Je n'ai pas assez de points ou quoi que ce soit pour modifier sa question, et je ne pense pas que toutes ces informations devraient être ajoutées dans un commentaire. Donc, jusqu'à ce que quelqu'un modifie sa question, j'ajouterai simplement qu'il s'agit d'une extension de la réponse d'Andy E (comme j'aurais dû le faire).
Jaacko Torus

Je pense que ça va maintenant :)
Jared Smith

1

Essaye ça:

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

1

Si vous ne souhaitez déplacer qu'un seul élément d'une position arbitraire à la fin du tableau, cela devrait fonctionner:

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

Si vous souhaitez déplacer plusieurs éléments d'une position arbitraire à la fin, vous pouvez faire:

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

Si vous souhaitez déplacer plusieurs éléments d'une position arbitraire à une position arbitraire, essayez:

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

En tant que solution modifiable simple, vous pouvez appeler splice deux fois de suite:

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

D'autre part, une solution simple non modifiable pourrait utiliser slice puisque cette méthode retourne une copie d'une section du tableau d'origine sans la modifier:

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

-2

Réorganiser son travail de cette façon

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

J'espère que cela fonctionnera


1
Qu'est-ce que cela ajoute aux réponses existantes?
Jared Smith
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.