Javascript'te bir dizinin başına nasıl yeni dizi öğeleri ekleyebilirim?


1585

Ben bir dizi başında öğeleri eklemek veya başa eklemek gerekir.

Örneğin, dizim aşağıdaki gibi görünüyorsa:

[23, 45, 12, 67]

Ve AJAX çağrımın yanıtı 34, güncel dizi aşağıdaki gibi olmasını istiyorum:

[34, 23, 45, 12, 67]

Şu anda böyle yapmayı planlıyorum:

var newArray = [];
newArray.push(response);

for (var i = 0; i < theArray.length; i++) {
    newArray.push(theArray[i]);
}

theArray = newArray;
delete newArray;

Bunu yapmanın daha iyi bir yolu var mı? Javascript'te bunu yapan herhangi bir yerleşik işlev var mı?

Metodumun karmaşıklığı O(n)ve daha iyi uygulamaları görmek gerçekten ilginç olurdu.


9
Bilginize: Bir dizinin başına sürekli olarak bir öğe eklemeniz gerekiyorsa , her zaman çağırmak yerine pushifadeleri ve ardından gelen çağrıyı kullanmak daha hızlıdır . reverseunshift
Jenny O'Reilly

2
@ JennyO'Reilly bunu bir cevap olarak göndermelisin. Kullanım durumumla mükemmel şekilde eşleşti. teşekkürler
rob

2
Performans testleri: jsperf.com/adding-element-to-the-array-start Ancak sonuçlar her tarayıcı için farklıdır.
Avernikoz

Yanıtlar:


2811

Kullanın unshift. pushDizinin başlangıcına bitiş yerine öğeler eklemesi dışında gibidir .

  • unshift/ push- dizinin başına / sonuna bir öğe ekle
  • shift/ pop - bir dizinin ilk / son öğesini kaldırır ve döndürür

Basit bir diyagram ...

   unshift -> array <- push
   shift   <- array -> pop

ve grafik:

          add  remove  start  end
   push    X                   X
    pop           X            X
unshift    X             X
  shift           X      X

Check out MDN Dizisi belgelerine . Bir diziden öğeleri itme / pop yapma yeteneğine sahip olan hemen hemen her dil, öğelerin kaydırma / kaydırma (bazen push_front/ olarak da adlandırılır pop_front) yeteneğine sahip olacaktır , bunları asla kendiniz uygulamalısınız.


Yorumlarda belirtildiği gibi, orijinal dizinizi mutasyona uğratmaktan kaçınmak istiyorsanız, concatiki veya daha fazla diziyi birleştiren kullanabilirsiniz. Tek bir elemanı mevcut bir dizinin önüne veya arkasına işlevsel olarak itmek için bunu kullanabilirsiniz; bunu yapmak için yeni öğeyi tek bir öğe dizisine dönüştürmeniz gerekir:

const array = [ 3, 2, 1 ]

const newFirstElement = 4

const newArray = [newFirstElement].concat(array) // [ 4, 3, 2, 1 ]

concatöğeleri de ekleyebilir. Argümanları concatherhangi bir türde olabilir; zaten bir dizi değilse, tek öğeli bir diziye örtülü olarak sarılırlar:

const array = [ 3, 2, 1 ]

const newLastElement  = 0

// Both of these lines are equivalent:
const newArray1 = array.concat(newLastElement)   // [ 3, 2, 1, 0 ]
const newArray2 = array.concat([newLastElement]) // [ 3, 2, 1, 0 ]

51
concatYeni diziyi döndürdüğü için kullanmak tercih edilebilir. Zincirleme için çok faydalıdır. [thingToInsertToFront].concat(originalArray).reduce(fn).reverse().map(fn)vb ... Eğer kullanırsanız unshift, o zincirleme yapamazsınız çünkü geri döndüğünüz tek şey uzunluğudur.
StJohn3D

4
shift / unshift, bas / pop, ekleme. Bu tür yöntemler için çok mantıklı isimler.
linuxunil

1397

dizi işlemleri resmi

var a = [23, 45, 12, 67];
a.unshift(34);
console.log(a); // [34, 23, 45, 12, 67]


117
İnsanların günlük olarak kullanılan 4 işlev için görsel bir kılavuza ihtiyaç duymasının nedeni, şifrelenmiş işlev adlarıdır ... Neden kaydırma, Ekle olarak adlandırılmıyor? Shift Kaldır olmalıdır. vb ...
Pascal

76
// Kaydırmaya neden Ekle adı verilmiyor? // Dizi öğelerine yığın gibi davranıldığı C programlama dilinin kurallarından geliyor. ( tam bir açıklama için perlmonks.org/?node_id=613129 adresine bakın )
dreftymac

25
@Pascal Hayır, ekleme ve kaldırma bunun için özellikle kötü adlar olacaktır; dizinin önüne ekleme / çıkarma yerine rastgele erişim anlamına gelir
meagar


27
DNA referansını seviyorum
Hunter WebDev

235

ES6 ile forma operatörünü kullanın ...:

DEMO

var arr = [23, 45, 12, 67];
arr = [34, ...arr]; // RESULT : [34,23, 45, 12, 67]

console.log(arr)


19
ayrıca saf işlevler için yararlı yeni bir dizi oluşturur
devonj

buradaki performans etkisi nedir? Unshift () kullanmaktan daha yavaş mı?
Peter T.

1
Elbette, değişmez bir dizi olduğu için daha yavaş olacaktır (yeni bir dizi oluşturma). Büyük bir dizi ile çalışıyorsanız veya performans ilk gereksiniminizse, lütfen concatbunun yerine kullanmayı düşünün .
Abdennour TOUMI

performansı 2018'de önemli değil, tarayıcıdaki ve düğümdeki yeni sürümler aynı performansı alıyor
stackdave

75

Bunu yapmanın başka bir yolu concat

var arr = [1, 2, 3, 4, 5, 6, 7];
console.log([0].concat(arr));

Arasındaki fark concatve unshiftolmasıdır concatdöner yeni dizi. Aralarındaki performans burada bulunabilir .

function fn_unshift() {
  arr.unshift(0);
  return arr;
}

function fn_concat_init() {
  return [0].concat(arr)
}

İşte test sonucu

resim açıklamasını buraya girin


Cevabınızın, referans eklemekten ayrı olarak her ikisinin performans karşılaştırmasını eklemesi iyi olacaktır.
Ivan De Paz Centeno

Sadece var biz v2 bırakmadan üzerinde çalışırken jsPerf geçici olarak kullanılamıyor. Lütfen bağlantıdan daha sonra tekrar deneyin . Sonuçları bunlara bağlamak yerine eklemek için başka bir iyi neden.
Tigger

Ön sonuç:: unshift25.510 ± 3.18% 99% daha yavaş concat: 2.436.894 ± 3.39% en hızlı
Aydınlatıcı

En son Safari'de fn_unshift () daha hızlı çalışır.
passatgt

En son Safari'de (v 10), fn_unshift () tekrar yavaşlar.
rmcsharry

45

Hızlı Hileleri:

Shift / unshift ve push / pop terimleri, en azından C programlamaya aşina olmayabilecek kişiler için biraz kafa karıştırıcı olabilir.

Lingo'ya aşina değilseniz, işte hatırlamak daha kolay olabilecek alternatif terimlerin hızlı bir çevirisi:

* array_unshift()  -  (aka Prepend ;; InsertBefore ;; InsertAtBegin )     
* array_shift()    -  (aka UnPrepend ;; RemoveBefore  ;; RemoveFromBegin )

* array_push()     -  (aka Append ;; InsertAfter   ;; InsertAtEnd )     
* array_pop()      -  (aka UnAppend ;; RemoveAfter   ;; RemoveFromEnd ) 

20

bir diziniz var: var arr = [23, 45, 12, 67];

Başlangıca bir öğe eklemek için şunu kullanmak istiyorsunuz splice:

var arr = [23, 45, 12, 67];
arr.splice(0, 0, 34)
console.log(arr);


arr splice (0, arrlen uzunluğu, 34);
Lior Elrom

1
@LiorElrom snippet'iniz ne yapıyor?
Janus Troelsen

@poushy tarayıcıya özel, Firefox 54'te unshift% 50 daha hızlı (ancak çoğunlukla daha okunabilir)
icl7126

@poushy Artık değil. Çok daha yavaş.
Andrew

17

Mutate olmadan

Aslında tüm unshift/ pushve shift/ pop mutasyon kökenli dizisi.

unshift/ push/ Başlamak sonu ve beri var diziye bir öğe eklemek shift/ popBir dizinin başlangıcı / ucundan bir öğeyi kaldırmak.

Ancak, bir diziye mutasyon olmadan öğe eklemenin birkaç yolu vardır. sonuç yeni bir dizidir, dizinin sonuna eklemek için aşağıdaki kodu kullanın:

const originArray = ['one', 'two', 'three'];
const newItem = 4;

const newArray = originArray.concat(newItem); // ES5
const newArray2 = [...originArray, newItem]; // ES6+

Orijinal dizinin başına eklemek için aşağıdaki kodu kullanın:

const originArray = ['one', 'two', 'three'];
const newItem = 0;

const newArray = (originArray.slice().reverse().concat(newItem)).reverse(); // ES5
const newArray2 = [newItem, ...originArray]; // ES6+

Yukarıdaki yolla, mutasyon olmadan bir dizinin başına / sonuna eklersiniz.


sliceSonunda originArraydeğişebilirliğini önlemek için bir işlev koydum .
Ahmad Khani

1
Müthiş! (Redux) Devlet yönetimi söz konusu olduğunda ... bu cevap değerlidir!
Pedro Ferreira

1
Bu doğru yol!
mmm

10

ES6 yıkımını kullanma: (orijinal diziden mutasyondan kaçınma)

const newArr = [item, ...oldArr]



8

Bir dizinin başına sürekli olarak bir öğe eklemeniz gerekirse , her zaman çağırmak yerine pushifadeleri ve ardından gelen çağrıyı kullanmak daha hızlıdır .reverseunshift

Karşılaştırma testi: http://jsben.ch/kLIYf


1
Not: ilk dizi boş olmalıdır.
192kb

5

Kullanarak splicebir diziye başlangıçta bir öğe ekleriz:

arrName.splice( 0, 0, 'newName1' );

Doğru bir cevap. Teşekkür ederim Srikrushna
Khanh Tran
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.