Dizileri yeniden sıralama


100

Diyelim ki şuna benzeyen bir dizim var:

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

Bir öğeyi başka bir konuma nasıl taşıyabilirim?

Mesela {artist:"Lalo Schifrin", title:"Shifting Gears"}sonuna gitmek istiyorum .

Splice kullanmayı denedim, şöyle:

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

Ama işe yaramıyor.


3
"Çalışmıyor" ne anlama geliyor - bir hata veriyor mu, hiçbir şeyi değiştirmiyor mu, dizinizi istemediğiniz bir şekilde değiştiriyor mu? Bana mantıklı görünüyor.
Jacob Mattison

Yanıtlar:


227

Sözdizimi Array.spliceşöyledir:

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

Nerede:

  • dizin , dizideki öğeleri kaldırmaya başlamak istediğiniz konumdur
  • kaç öğe dizinden çıkarmak istediğiniz öğedir
  • element1, ..., elementX , konum dizininden eklenmesini istediğiniz öğelerdir .

Bu splice(), ilettiğiniz argümanlara bağlı olarak bir dizideki öğeleri kaldırmak, eklemek veya öğeleri değiştirmek için kullanılabileceği anlamına gelir .

Kaldırılan elemanların bir dizisini döndürdüğünü unutmayın.

Güzel ve genel bir şey şöyle olabilir:

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

O zaman şunu kullan:

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

Diyagram:

Algoritma diyagramı


17
Bu iyi bir cevaptır ve bir splice () içindeki splice () işi iyi yapar. Bununla birlikte, Dizi prototipine bir move () yöntemi eklemenin "Maymun Yaması" olarak adlandırıldığına ve genellikle kötü uygulama olarak kabul edildiğine dikkat edilmelidir. stackoverflow.com/questions/5741877/…
Aaron Cicali

22

Dizinleri biliyorsanız, aşağıdaki gibi basit bir işlevle öğeleri kolayca değiştirebilirsiniz:

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

Dizi dizinleri, dizi nesnesinin yalnızca özellikleridir, dolayısıyla değerlerini takas edebilirsiniz.


Teşekkürler @CMS. Acımasız ı 3 1 gibi bir 2 ve 2 olarak takas 1'e istediğim 1. pozisyonuna 3 nesneyi seçerseniz, Örnek için ... sırasını değiştirmek istemiyorsanız takas Eğer
Peri

14

İşte ilgilenenler için değişmez bir versiyon:

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

Merhaba, bu fonksiyonun yukarıdaki cevaba kıyasla faydalarını bana açıklayabilir misiniz?
Xogno

1
Bu çözüm, orijinal öğeyi değiştirmez, ancak taşınan girişle yeni bir dizi döndürür.
chmanie

7

Öğeyi kaldırırken splice çağrısındaki ilk parametre olarak 2'yi 1'e değiştirin:

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

1
playlist.splice (2,0, tmp [0]) olmalıdır; Sağ?
Crisboot

7

ES6 ile bunun gibi bir şey yapabilirsiniz:

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]

2
Bu, iki elemanın konumunu değiştirir. Soru yeniden sipariş içindir.
BY

6

Kaydın şu anda nerede olduğunu bilmiyorsanız, her zaman sıralama yöntemini kullanabilirsiniz:

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

1
Peki yareturn +(a.artist == "Lalo Schifrin")
Funkodebat

2
@Funko, kısalığı ayrıntıya tercih ederseniz, bunu yapabilirsiniz.
Andy E

2

DÜZENLEME: Lütfen Andy'nin cevabına bir göz atın çünkü cevabı önce geldi ve bu sadece onun

Bunun eski bir soru olduğunu biliyorum, ancak buna değer olduğunu düşünüyorum Array.prototype.sort().

İşte bağlantıyla birlikte MDN'den bir örnek

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

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

Neyse ki sadece sayılarla çalışmıyor:

arr.sort([compareFunction])

compareFunction

Sıralama düzenini tanımlayan bir işlevi belirtir. Atlanırsa, dizi, her öğenin dize dönüşümüne göre her karakterin Unicode kod noktası değerine göre sıralanır.

Bunları adlarına göre sipariş ettiğinizi fark ettim:

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

Onları soyadına göre sipariş etmek istiyorsanız, ya her ikisi için de bir anahtarınızın olması first_nameve last_nameya da XD yapamadığım bir normal ifade sihri yapmanız gerekeceğini unutmayın.

Umarım yardımcı olur :)


Bu, bu cevaba ilişkin bir düzenleme veya yorum olmalıdır .
Jared Smith

@JaredSmith Oops! Cevabını görmedim. Sorusunu düzenlemek için yeterli puanım veya neyim yok ve tüm bu bilgilerin bir yoruma eklenmesi gerektiğini düşünmüyorum. Yani birisi sorusunu düzenleyinceye kadar, bunun Andy E'nin cevabının bir uzantısı olduğunu ekleyeceğim (yapmam gerektiği gibi).
Jaacko Torus

Sanırım şimdi iyi :)
Jared Smith

1

Bunu dene:

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

1

Sadece bir öğeyi rastgele bir konumdan dizinin sonuna taşımak istiyorsanız, bu çalışmalıdır:

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

Birden fazla öğeyi rastgele bir konumdan sona taşımak istiyorsanız şunları yapabilirsiniz:

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

Birden fazla öğeyi rastgele bir konumdan rastgele bir konuma taşımak istiyorsanız şunu deneyin:

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

Basit bir değiştirilebilir çözüm olarak splice'ı art arda iki kez çağırabilirsiniz:

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

Öte yandan, bu yöntem orijinal diziden bir bölümün bir kopyasını değiştirmeden döndürdüğünden, basit bir değişmez çözüm dilim kullanabilir:

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

-2

Çalışmasını Bu Şekilde Yeniden Sırala

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

Umarım bu işe yarar


1
Bu, mevcut cevaplara ne ekler?
Jared Smith
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.