web-dev-qa-db-fra.com

Réorganisation des matrices

Dis, 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 puis-je déplacer un élément vers une autre position?

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

J'ai essayé d'utiliser des épissures, comme ceci:

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

Mais ça ne marche pas.

70
Wurlitzer

La syntaxe de Array.splice est la suivante:

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

Où:

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

Cela signifie que 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 transmis.

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

Quelque chose de gentil et 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:

 Algorithm diagram

174
Matt

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.

17
CMS

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

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

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

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
});
3
Andy E

Si vous ne voulez jamais 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 quelconque à la fin, vous pouvez procéder comme suit:

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

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
arthurDent

Essaye ça: 

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

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 ça va marcher

0
Periyasamy

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 et immuable pourrait utiliser slice puisque cette méthode renvoie 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)]
0
David