Menyusun ulang array

98

Katakanlah, saya memiliki array yang terlihat seperti ini:

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

Bagaimana cara memindahkan elemen ke posisi lain?

Saya ingin pindah misalnya, {artist:"Lalo Schifrin", title:"Shifting Gears"}sampai akhir.

Saya mencoba menggunakan sambungan, seperti ini:

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

Tapi itu tidak berhasil.

Wurlitzer
sumber
3
Apa yang dimaksud dengan "tidak berfungsi" - apakah itu menimbulkan kesalahan, apakah itu tidak mengubah apa pun, apakah itu mengubah larik Anda dengan cara yang tidak Anda inginkan? Itu terlihat masuk akal bagi saya.
Jacob Mattison

Jawaban:

222

Sintaksnya Array.spliceadalah:

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

Dimana:

  • index adalah posisi dalam larik yang elemennya ingin Anda hapus
  • howmany adalah berapa banyak elemen yang ingin Anda hapus dari indeks
  • element1, ..., elementX adalah elemen yang ingin disisipkan dari indeks posisi .

Artinya, splice()dapat digunakan untuk menghapus elemen, menambahkan elemen, atau mengganti elemen dalam array, bergantung pada argumen yang Anda berikan.

Perhatikan bahwa ini mengembalikan larik elemen yang dihapus.

Sesuatu yang bagus dan umum adalah:

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

Kemudian gunakan saja:

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

Diagram:

Diagram algoritme

Matt
sumber
17
Ini adalah jawaban yang bagus, dan splice () dalam sebuah splice () melakukan pekerjaan dengan baik. Namun, perlu dicatat bahwa menambahkan metode move () ke prototipe Array disebut "Monkey Patching" dan biasanya dianggap praktik yang buruk. stackoverflow.com/questions/5741877/…
Aaron Cicali
20

Jika Anda mengetahui indeksnya, Anda dapat dengan mudah menukar elemen, dengan fungsi sederhana seperti ini:

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

Indeks array hanyalah properti dari objek array, jadi Anda dapat menukar nilainya.

Christian C. Salvadó
sumber
Terima kasih, @CMS. Jika saya menukar berarti tidak ingin mengganti pesanan ... Sebagai Contoh, Jika saya memilih objek ke-3 ke posisi pertama saya ingin menukar 1 sebagai 2 dan 2 sebagai 3 sebagai 1
Peri
13

Ini adalah versi yang tidak dapat diubah untuk mereka yang tertarik:

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
sumber
Hai, dapatkah Anda menjelaskan kepada saya manfaat dari fungsi ini dibandingkan jawaban di atas?
Xogno
1
Solusi ini tidak mengubah elemen asli tetapi mengembalikan larik baru dengan entri yang dipindahkan.
chmanie
7

Ubah 2 menjadi 1 sebagai parameter pertama dalam panggilan sambatan saat menghapus elemen:

var tmp = playlist.splice(1, 1);
playlist.splice(2, 0, tmp[0]);
Trevor
sumber
1
itu harus playlist.splice (2,0, tmp [0]); Baik?
Crisboot
7

Dengan ES6 Anda dapat melakukan sesuatu seperti ini:

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
sumber
1
Ini menukar posisi dua elemen. Pertanyaan untuk menyusun ulang.
OLEH
5

Anda selalu dapat menggunakan metode sortir, jika Anda tidak tahu di mana record saat ini:

playlist.sort(function (a, b) {
    return a.artist == "Lalo Schifrin" 
               ? 1    // Move it down the list
               : 0;   // Keep it the same
});
Andy E
sumber
1
Bagaimana denganreturn +(a.artist == "Lalo Schifrin")
Funkodebat
2
@Funko Anda bisa melakukan itu, jika Anda lebih suka singkat daripada verbositas.
Andy E
2

EDIT: Silakan lihat jawaban Andy karena jawabannya datang lebih dulu dan ini semata-mata perpanjangan dari miliknya

Saya tahu ini adalah pertanyaan lama, tapi menurut saya itu layak untuk dimasukkan Array.prototype.sort().

Berikut contoh dari MDN bersama dengan tautannya

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

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

Untungnya, ini tidak hanya berfungsi dengan angka:

arr.sort([compareFunction])

compareFunction

Menentukan fungsi yang menentukan urutan sortir. Jika dihilangkan, larik akan diurutkan sesuai dengan nilai poin kode Unicode setiap karakter, sesuai dengan konversi string dari setiap elemen.

Saya perhatikan bahwa Anda memesannya dengan nama depan:

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

perhatikan bahwa jika Anda ingin memesannya dengan nama belakang Anda harus memiliki kunci untuk keduanya first_name& last_nameatau melakukan sihir regex, yang saya tidak dapat melakukan XD

Semoga membantu :)

Jaacko Torus
sumber
Ini harus menjadi edit atau komentar untuk jawaban ini .
Jared Smith
@JaredS Ups! Saya tidak melihat jawabannya. Saya tidak memiliki cukup poin atau apa pun untuk mengedit pertanyaannya, dan saya rasa semua informasi ini tidak perlu ditambahkan dalam komentar. Jadi sampai seseorang mengedit pertanyaannya, saya hanya akan menambahkan bahwa ini adalah perpanjangan dari jawaban Andy E (seperti yang seharusnya saya lakukan).
Jaacko Torus
Saya pikir tidak apa-apa sekarang :)
Jared Smith
1

Coba ini:

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

Jika Anda hanya ingin memindahkan satu item dari posisi arbitrer ke akhir larik, ini seharusnya berfungsi:

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

Jika Anda ingin memindahkan beberapa item dari beberapa posisi arbitrer ke akhir, Anda dapat melakukan:

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

Jika Anda ingin memindahkan beberapa item dari beberapa posisi arbitrer ke beberapa posisi arbitrer, coba:

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
sumber
0

Sebagai solusi sederhana yang dapat diubah, Anda dapat memanggil sambungan dua kali berturut-turut:

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

Di sisi lain, solusi sederhana yang tidak dapat diubah dapat menggunakan slice karena metode ini mengembalikan salinan bagian dari larik asli tanpa mengubahnya:

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

Susun ulang pekerjaannya dengan Cara Ini

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

Saya harap ini akan berhasil

Peri
sumber
1
Apa yang ditambahkan di atas jawaban yang ada?
Jared Smith