Apa cara yang lebih efisien untuk memasukkan array ke dalam array lain.
a1 = [1,2,3,4,5];
a2 = [21,22];
newArray - a1.insertAt(2,a2) -> [1,2, 21,22, 3,4,5];
Iterasi a2 menggunakan sambatan terlihat agak buruk dari sudut pandang kinerja jika array a2 besar.
Terima kasih.
Jawaban:
Anda dapat menggunakan
splice
kombinasi dengan beberapaapply
tipuan:a1 = [1,2,3,4,5]; a2 = [21,22]; a1.splice.apply(a1, [2, 0].concat(a2)); console.log(a1); // [1, 2, 21, 22, 3, 4, 5];
Di ES2015 +, Anda dapat menggunakan operator penyebaran untuk membuatnya sedikit lebih bagus
a1.splice(2, 0, ...a2);
sumber
apply
akan memunculkan pengecualian stackoverflow. jsfiddle.net/DcHCY Juga terjadi di jsPerf Saya percaya pada FF dan IE ambang batasnya sekitar 500ktarget.slice(0, insertIndex).concat(insertArr, target.slice(insertIndex));
jsperf.com/inserting-an-array-within-an-arraySekarang Anda dapat melakukan ini jika menggunakan ES2015 atau lebih baru:
var a1 = [1,2,3,4,5]; var a2 = [21,22]; a1.splice(2, 0, ...a2); console.log(a1) // => [1,2,21,22,3,4,5]
Lihat ini untuk dokumentasi tentang operator spread (...) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator
sumber
Apakah itu salah pada awalnya. Seharusnya digunakan
concat()
sebagai gantinya.var a1 = [1,2,3,4,5], a2 = [21,22], startIndex = 0, insertionIndex = 2, result; result = a1.slice(startIndex, insertionIndex).concat(a2).concat(a1.slice(insertionIndex));
Contoh: http://jsfiddle.net/f3cae/1/
Ekspresi ini menggunakan
slice(0, 2)
[docs] untuk mengembalikan dua elemen pertamaa1
(di mana0
indeks awal, dan2
elemen deleteCount, meskipuna1
tidak diubah).Hasil antara :
[1,2]
Ini kemudian menggunakan
concat(a2)
[docs] untuk ditambahkana2
ke akhir[1,2]
.Hasil tengah :
[1,2,21,22]
.Selanjutnya,
a1.slice(2)
dipanggil dalam sebuah jejak.concat()
di ujung ekor ekspresi ini, yang berjumlah[1,2,21,22].concat(a1.slice(2))
.Panggilan ke
slice(2)
, memiliki argumen bilangan bulat positif, akan mengembalikan semua elemen setelah elemen ke-2, dihitung dengan bilangan asli (seperti dalam, ada lima elemen, jadi[3,4,5]
akan dikembalikan daria1
). Cara lain untuk mengatakan ini adalah bahwa argumen indeks integer tunggal memberi tahua1.slice()
di posisi mana dalam array untuk mulai mengembalikan elemen (indeks 2 adalah elemen ketiga).Hasil antara :
[1,2,21,22].concat([3,4,5])
Akhirnya, detik
.concat()
ditambahkan[3,4,5]
ke akhir[1,2,21,22]
.Hasil :
[1,2,21,22,3,4,5]
Mungkin tergoda untuk mengubahnya
Array.prototype
, tetapi seseorang dapat dengan mudah memperluas objek Array menggunakan warisan prototypal dan menyuntikkan objek baru tersebut ke dalam proyek Anda.Namun, bagi mereka yang hidup di pinggir ...
Contoh: http://jsfiddle.net/f3cae/2/
Array.prototype.injectArray = function( idx, arr ) { return this.slice( 0, idx ).concat( arr ).concat( this.slice( idx ) ); }; var a1 = [1,2,3,4,5]; var a2 = [21,22]; var result = a1.injectArray( 2, a2 );
sumber
The spread Operator memungkinkan ekspresi diperluas di tempat-tempat di mana beberapa argumen (untuk panggilan fungsi) atau beberapa elemen (untuk literal array) diharapkan.
a2 = [21,22]; a1 = [1,2,...a2,3,4,5];//...a2 is use of spread operator console.log(a1);
sumber
Saya ingin menemukan cara untuk melakukan ini dengan
splice()
dan tanpa iterasi: http://jsfiddle.net/jfriend00/W9n27/ .a1 = [1,2,3,4,5]; a2 = [21,22]; a2.unshift(2, 0); // put first two params to splice onto front of array a1.splice.apply(a1, a2); // pass array as arguments parameter to splice console.log(a1); // [1, 2, 21, 22, 3, 4, 5];
Dalam bentuk fungsi tujuan umum:
function arrayInsertAt(destArray, pos, arrayToInsert) { var args = []; args.push(pos); // where to insert args.push(0); // nothing to remove args = args.concat(arrayToInsert); // add on array to insert destArray.splice.apply(destArray, args); // splice it in }
sumber
a2
larik juga, yang mungkin sangat tidak diinginkan. Selain itu, Anda tidak perlu pergi keArray.prototype
saat Anda memiliki fungsi slice di sanaa1
ataua2
.apply()
metode.Array.prototype.splice
vsa1.splice
:).concat
mengembalikan array baru, itu tidak mengubah yang sudah ada seperti itusplice
. Seharusnyaargs = args.concat(arrayToInsert);
Ada beberapa jawaban yang benar-benar kreatif untuk pertanyaan ini di sini. Berikut adalah solusi sederhana bagi mereka yang baru memulai dengan array. Ini dapat dibuat untuk bekerja sepenuhnya hingga ke browser yang mendukung ECMAScript 3, jika diinginkan.
Ketahui sesuatu tentang sambungan sebelum memulai.
Jaringan Pengembang Mozilla: Array.prototype.splice ()
Pertama, pahami dua bentuk penting dari
.splice()
.let a1 = [1,2,3,4], a2 = [1,2];
Metode 1) Hapus elemen x (deleteCount), mulai dari indeks yang diinginkan.
let startIndex = 0, deleteCount = 2; a1.splice(startIndex, deleteCount); // returns [1,2], a1 would be [3,4]
Metode 2) Hapus elemen setelah indeks awal yang diinginkan ke akhir array.
a1.splice(2); // returns [3,4], a1 would be [1,2]
Dengan menggunakan
.splice()
, tujuannya adalah untuk membagia1
menjadi array kepala dan ekor dengan menggunakan salah satu dari dua bentuk di atas.Menggunakan metode # 1, nilai yang dikembalikan akan menjadi kepala, dan
a1
ekor.let head = a1.splice(startIndex, deleteCount); // returns [1,2], a1 would be [3,4]
Sekarang, dalam satu gerakan, satukan kepala, badan (
a2
), dan ekorDengan demikian, solusi ini lebih seperti dunia nyata daripada solusi lain yang disajikan sejauh ini. Bukankah ini yang akan Anda lakukan dengan Lego? ;-) Ini adalah fungsi, dilakukan dengan menggunakan metode # 2.
/** *@param target Array The array to be split up into a head and tail. *@param body Array The array to be inserted between the head and tail. *@param startIndex Integer Where to split the target array. */ function insertArray(target, body, startIndex) { let tail = target.splice(startIndex); // target is now [1,2] and the head return [].concat(target, body, tail); } let newArray = insertArray([1, 2, 3, 4], ["a", "b"], 2); // [1, 2, "a", "b", 3, 4]
Singkat:
/** *@param target Array The array to be split up into a head and tail. *@param body Array The array to be inserted between the head and tail. *@param startIndex Integer Where to split the target array. */ function insertArray(target, body, startIndex) { return [].concat(target, body, target.splice(startIndex)); }
Lebih aman:
/** *@param target Array The array to be split up into a head and tail. *@param body Array The array to be inserted between the head and tail. *@param startIndex Integer Where to split the target array. *@throws Error The value for startIndex must fall between the first and last index, exclusive. */ function insertArray(target, body, startIndex) { const ARRAY_START = 0, ARRAY_END = target.length - 1, ARRAY_NEG_END = -1, START_INDEX_MAGNITUDE = Math.abs(startIndex); if (startIndex === ARRAY_START) { throw new Error("The value for startIndex cannot be zero (0)."); } if (startIndex === ARRAY_END || startIndex === ARRAY_NEG_END) { throw new Error("The startIndex cannot be equal to the last index in target, or -1."); } if (START_INDEX_MAGNITUDE >= ARRAY_END) { throw new Error("The absolute value of startIndex must be less than the last index."); } return [].concat(target, body, target.splice(startIndex)); }
Keuntungan dari solusi ini meliputi:
1) Premis sederhana mendominasi solusi - isi larik kosong.
2) Tata nama kepala, badan, dan ekor terasa alami.
3) Tidak ada panggilan ganda ke
.slice()
. Tidak ada pemotongan sama sekali.4) Tidak
.apply()
. Sangat tidak perlu.5) Menghindari rangkaian metode.
6) Bekerja di ECMAScript 3 dan 5 hanya dengan menggunakan
var
alih-alihlet
atauconst
.** 7) Memastikan bahwa akan ada kepala dan ekor untuk ditampar ke tubuh, tidak seperti banyak solusi lain yang disajikan. Jika Anda menambahkan larik sebelum, atau setelah, batas, Anda setidaknya harus menggunakan
.concat()
!!!!Catatan: Penggunaan opearator penyebaran
...
membuat semua ini lebih mudah dilakukan.sumber
var a1 = [1,2,3,4,5]; var a2 = [21,22]; function injectAt(d, a1, a2) { for(var i=a1.length-1; i>=d; i--) { a1[i + a2.length] = a1[i]; } for(var i=0; i<a2.length; i++) { a1[i+d] = a2[i]; } } injectAt(2, a1, a2); alert(a1);
sumber
Ini versi saya tanpa trik khusus:
function insert_array(original_array, new_values, insert_index) { for (var i=0; i<new_values.length; i++) { original_array.splice((insert_index + i), 0, new_values[i]); } return original_array; }
sumber
.apply()
.Jika Anda ingin memasukkan array lain ke dalam array tanpa membuat yang baru, cara termudah adalah menggunakan salah satu
push
atauunshift
denganapply
Misalnya:
a1 = [1,2,3,4,5]; a2 = [21,22]; // Insert a1 at beginning of a2 a2.unshift.apply(a2,a1); // Insert a1 at end of a2 a2.push.apply(a2,a1);
Ini berfungsi karena keduanya
push
danunshift
mengambil sejumlah variabel argumen. Bonus, Anda dapat dengan mudah memilih ujung mana untuk melampirkan array!sumber
a1.concat(a2)
ataua2.concat(a1)
saya telah menemukan sesuatu yang lebih mudah dari apa yang Anda sarankan. Namun, masalahnya adalah memasukkan larik di antara batas larik, tidak secara eksklusif menambahkan larik ke awal atau akhir. ;-)Seperti yang disebutkan di utas lain, jawaban di atas tidak akan berfungsi dalam larik yang sangat besar (200 ribu elemen). Lihat jawaban alternatif di sini yang melibatkan sambungan dan dorongan manual: https://stackoverflow.com/a/41465578/1038326
Array.prototype.spliceArray = function(index, insertedArray) { var postArray = this.splice(index); inPlacePush(this, insertedArray); inPlacePush(this, postArray); function inPlacePush(targetArray, pushedArray) { // Not using forEach for browser compatability var pushedArrayLength = pushedArray.length; for (var index = 0; index < pushedArrayLength; index++) { targetArray.push(pushedArray[index]); } } }
sumber