คัดลอกรายการอาร์เรย์ไปยังอาร์เรย์อื่น


916

ฉันมีอาร์เรย์ JavaScript ที่ฉันต้องการที่จะผลักดันให้เป็นแถวใหม่dataArray newArrayยกเว้นฉันไม่ต้องการที่จะเป็นnewArray[0] dataArrayฉันต้องการผลักดันไอเท็มทั้งหมดลงในอาร์เรย์ใหม่:

var newArray = [];

newArray.pushValues(dataArray1);
newArray.pushValues(dataArray2);
// ...

หรือดีกว่า:

var newArray = new Array (
   dataArray1.values(),
   dataArray2.values(),
   // ... where values() (or something equivalent) would push the individual values into the array, rather than the array itself
);

ดังนั้นตอนนี้อาร์เรย์ใหม่จะมีค่าทั้งหมดของอาร์เรย์ข้อมูลแต่ละรายการ มีชวเลขเหมือนpushValuesมีอยู่หรือไม่ดังนั้นฉันไม่ต้องทำซ้ำในแต่ละรายการdataArrayเพิ่มรายการทีละรายการ?



นี่ควรเป็นคำตอบdavidwalsh.name/combining-js-arrays
starikovs

คำตอบ:


1248

ใช้ฟังก์ชันconcatดังนี้:

var arrayA = [1, 2];
var arrayB = [3, 4];
var newArray = arrayA.concat(arrayB);

ค่าของnewArrayจะเป็น[1, 2, 3, 4]( arrayAและarrayBยังคงไม่เปลี่ยนแปลงconcatสร้างและส่งกลับอาร์เรย์ใหม่สำหรับผลลัพธ์)



16
ฉันยอมรับว่าการแสดงของนักแสดงนั้นดีมาก แต่ไม่ได้เป็น concat ว่าสำหรับที่มีวัตถุประสงค์เพื่อconcatเพื่ออาร์เรย์? ดังนั้นมันควรจะเป็นมาตรฐาน หรือมีเรื่องอื่นที่ดีกว่าเกี่ยวกับการทำ concat และมันอาจช้าเพราะการใช้เอ็นจิน JS ของเบราว์เซอร์ไม่ดีหรือที่ใดก็ตามที่คุณใช้มัน? อาจได้รับการแก้ไขในหนึ่งวัน ฉันจะเลือกการบำรุงรักษาโค้ดด้วยการเพิ่มประสิทธิภาพความเร็วแฮ็ก อืม ....
Bitterblue

3
นอกจากนี้ฉันเพิ่ง benchmarked สถานการณ์: concat vs. push.apply Google Chrome: ได้อย่างรวดเร็ว (concat = ชนะ) Opera: ได้อย่างรวดเร็ว (concat = ชนะ) IE: ช้า (concat = ชนะ), Firefoxช้า (push.apply = ชนะ 10 ครั้งยังช้ากว่า concat ของ Chrome) ... พูดไม่ดี JS การดำเนินงานของเครื่องยนต์ .
Bitterblue

15
การต่อสองอาร์เรย์เข้าด้วยกันเป็นคำตอบที่ยอมรับได้อย่างไรสำหรับวิธีการผลักดันเข้าสู่อีกแถวหนึ่ง! นี่เป็นการดำเนินงานสองอย่างที่แตกต่างกัน
kaqqao

@kaqqao เพราะpushจะไม่ทำให้อาร์เรย์ของค่าแบน concatบรรลุคำถามที่ต้องการ
WiseGuyEh

644

หากอาร์เรย์ของคุณไม่ใหญ่มาก (ดูที่ caveat ด้านล่าง) คุณสามารถใช้push()วิธีการของอาร์เรย์ที่คุณต้องการผนวกค่า push()สามารถใช้หลายพารามิเตอร์เพื่อให้คุณสามารถใช้apply()วิธีการผ่านอาร์เรย์ของค่าที่จะผลักดันเป็นรายการของพารามิเตอร์ฟังก์ชั่น สิ่งนี้มีความได้เปรียบมากกว่าการใช้concat()การเพิ่มองค์ประกอบเข้ากับอาร์เรย์แทนการสร้างอาร์เรย์ใหม่

แต่ก็ดูเหมือนว่าสำหรับอาร์เรย์ขนาดใหญ่ (คำสั่งของ 100,000 คนหรือมากกว่า) เคล็ดลับนี้สามารถล้มเหลว สำหรับอาร์เรย์ดังกล่าวการใช้การวนซ้ำเป็นวิธีที่ดีกว่า ดูhttps://stackoverflow.com/a/17368101/96100สำหรับรายละเอียด

var newArray = [];
newArray.push.apply(newArray, dataArray1);
newArray.push.apply(newArray, dataArray2);

คุณอาจต้องการสรุปสิ่งนี้ลงในฟังก์ชั่น:

function pushArray(arr, arr2) {
    arr.push.apply(arr, arr2);
}

... หรือเพิ่มลงในArrayต้นแบบของ:

Array.prototype.pushArray = function(arr) {
    this.push.apply(this, arr);
};

var newArray = [];
newArray.pushArray(dataArray1);
newArray.pushArray(dataArray2);

... หรือเลียนแบบเดิมpush()วิธีการโดยการอนุญาตให้พารามิเตอร์ต่างๆโดยใช้ความจริงที่ว่าconcat()เช่นpush()ช่วยให้หลายพารามิเตอร์:

Array.prototype.pushArray = function() {
    this.push.apply(this, this.concat.apply([], arguments));
};

var newArray = [];
newArray.pushArray(dataArray1, dataArray2);

ต่อไปนี้เป็นตัวอย่างแบบลูปตามตัวอย่างล่าสุดเหมาะสำหรับอาร์เรย์ขนาดใหญ่และเบราว์เซอร์หลักทั้งหมดรวมถึง IE <= 8:

Array.prototype.pushArray = function() {
    var toPush = this.concat.apply([], arguments);
    for (var i = 0, len = toPush.length; i < len; ++i) {
        this.push(toPush[i]);
    }
};

9
หมายเหตุ: newArray.push.apply(newArray, dataArray1);ให้เหมือนกับArray.prototype.push.applay(newArray,dataArra1);

สิ่งนี้เข้ากันได้กับเบราว์เซอร์รุ่นเก่าหรือไม่
ดาเมียนÓ Ceallaigh


1
@ DamienÓCeallaigh: ใช่ ทั้งหมดนี้เข้ากันได้กับเบราว์เซอร์จะกลับไปเป็น IE 6 และแม้กระทั่งก่อนหน้า
Tim Down

นี่คือตัวอย่างที่ดีของการปฏิบัติการเขียนโปรแกรมที่ไม่ดี Array.prototype.concatไม่เลว แต่มันก็เข้าใจผิดและบางครั้งก็ใช้ผิด ภายใต้สถานการณ์เหล่านี้มันเป็นเพียงการเข้าใจผิด แต่ไม่ได้ใช้ในทางที่ผิด
Jack Giffin

444

ฉันจะเพิ่มคำตอบ "หลักฐานในอนาคต" อีกหนึ่งคำตอบ

ใน ECMAScript 6 คุณสามารถใช้ไวยากรณ์ Spread :

let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
arr1.push(...arr2);

console.log(arr1)

รูปแบบการแพร่กระจายยังไม่รวมอยู่ในเบราว์เซอร์หลักทั้งหมด สำหรับการทำงานร่วมกันในปัจจุบันเห็นนี้ (ปรับปรุงอย่างต่อเนื่อง) ตารางการทำงานร่วมกัน

อย่างไรก็ตามคุณสามารถใช้ไวยากรณ์การแพร่กระจายด้วยBabel.js

แก้ไข:

ดูคำตอบของ Jack Giffin ด้านล่างสำหรับความคิดเห็นเพิ่มเติมเกี่ยวกับประสิทธิภาพ ดูเหมือนว่า concat จะยังดีกว่าและเร็วกว่าผู้ให้บริการสเปรด


7
คุณยังสามารถใช้ตัวดำเนินการสเปรดถ้าคุณใช้ TypeScript หากคุณกำหนดเป้าหมาย ES5 newArray.apply(newArray, dataArray1)ก็จะรวบรวม
AJ Richardson

5
หมายเหตุ: หากคุณต้องการผลลัพธ์ในอาร์เรย์ที่สาม (ดังนั้นจึงไม่ต้องแก้ไข arr1 ตามคำถามแรกที่ดูเหมือนจะต้องการ) คุณสามารถทำ newArray = [... arr1, ... arr2]
สลัว

โอ้ฉันไม่รู้ ขอบคุณ ฉันได้เพิ่มความคิดเห็นแก้ไข
Karel Bílek

คล้ายกับวิธีที่ concat ใช้งานได้แล้วพร้อมโบนัสถาวร
Rob

@robertmylne ตัวดำเนินการสเปรดไม่ได้ปรับเปลี่ยนอาร์เรย์ดั้งเดิม แต่สร้างสำเนาใหม่ของเนื้อหาอาร์เรย์ทั้งหมดที่ละทิ้ง
Jack Giffin

145

พบวิธีที่สง่างามจากMDN

var vegetables = ['parsnip', 'potato'];
var moreVegs = ['celery', 'beetroot'];

// Merge the second array into the first one
// Equivalent to vegetables.push('celery', 'beetroot');
Array.prototype.push.apply(vegetables, moreVegs);

console.log(vegetables); // ['parsnip', 'potato', 'celery', 'beetroot']

หรือคุณสามารถใช้spread operatorคุณสมบัติของ ES6:

let fruits = [ 'apple', 'banana'];
const moreFruits = [ 'orange', 'plum' ];

fruits.push(...moreFruits); // ["apple", "banana", "orange", "plum"]

1
นี่ไม่ใช่คำถามที่ถาม คำถามกำลังถามหาวิธีในการสร้างอาร์เรย์ใหม่ในแต่ละครั้งไม่ได้แก้ไขอาร์เรย์เก่า
Jack Giffin

13
var a=new Array('a','b','c');
var b=new Array('d','e','f');
var d=new Array('x','y','z');
var c=a.concat(b,d)

นั่นช่วยแก้ปัญหาของคุณหรือไม่?


13

ต่อไปนี้ดูเหมือนง่ายที่สุดสำหรับฉัน:

var newArray = dataArray1.slice();
newArray.push.apply(newArray, dataArray2);

ในขณะที่ "push" รับจำนวนตัวแปรที่ขัดแย้งกันคุณสามารถใช้applyวิธีการของpushฟังก์ชั่นเพื่อผลักองค์ประกอบทั้งหมดของอาร์เรย์อื่น มันสร้างสายที่จะผลักดันโดยใช้อาร์กิวเมนต์แรก ("newArray" ที่นี่) เป็น "นี้" และองค์ประกอบของอาร์เรย์เป็นอาร์กิวเมนต์ที่เหลือ

sliceในคำสั่งแรกได้รับสำเนาของอาร์เรย์แรกเพื่อให้คุณไม่แก้ไขมัน

อัปเดตหากคุณใช้จาวาสคริปต์ในเวอร์ชันที่มีชิ้นส่วนคุณสามารถทำให้pushนิพจน์ง่ายขึ้นเพื่อ:

newArray.push(...dataArray2)

1
มีการกล่าวถึงที่นี่ที่ MDNเป็นตัวอย่างสำหรับ "การผสานสองอาร์เรย์"
เหี่ยวแห้ง

12

ฟังก์ชั่นด้านล่างไม่มีปัญหากับความยาวของอาร์เรย์และทำงานได้ดีกว่าโซลูชันที่แนะนำทั้งหมด:

function pushArray(list, other) {
    var len = other.length;
    var start = list.length;
    list.length = start + len;
    for (var i = 0; i < len; i++ , start++) {
        list[start] = other[i];
    }
}

น่าเสียดายที่ jspref ปฏิเสธที่จะยอมรับผลงานของฉันดังนั้นนี่คือผลลัพธ์โดยใช้ benchmark.js

        Name            |   ops/sec   |  ± %  | runs sampled
for loop and push       |      177506 |  0.92 | 63
Push Apply              |      234280 |  0.77 | 66
spread operator         |      259725 |  0.40 | 67
set length and for loop |      284223 |  0.41 | 66

ที่ไหน

สำหรับ loop และ push คือ:

    for (var i = 0, l = source.length; i < l; i++) {
        target.push(source[i]);
    }

กดใช้:

target.push.apply(target, source);

ผู้ประกอบการแพร่กระจาย:

    target.push(...source);

และในที่สุด 'ความยาวที่กำหนดและสำหรับวง' เป็นฟังก์ชั่นดังกล่าวข้างต้น


คำถามนี้กำลังมองหาวิธีการสร้างอาร์เรย์ใหม่ในแต่ละครั้งไม่ได้แก้ไขอาร์เรย์ที่มีอยู่
Jack Giffin

10

𝗥𝗲𝘀𝗲𝗮𝗿𝗰𝗵𝗔𝗻𝗱𝗥𝗲𝘀𝘂𝗹𝘁𝘀

สำหรับข้อเท็จจริงการทดสอบประสิทธิภาพที่ jsperfและการตรวจสอบบางสิ่งในคอนโซลจะดำเนินการ สำหรับการวิจัยirt.org เว็บไซต์ถูกนำมาใช้ ด้านล่างคือชุดของแหล่งข้อมูลเหล่านี้ทั้งหมดที่รวมเข้าด้วยกันพร้อมฟังก์ชั่นตัวอย่างที่ด้านล่าง

╔═══════════════╦══════╦═════════════════╦════════ ═══════╦═════════╦══════════╗
║วิธีการ║ควบคุม & กดส่งใช้ app กด. ใช้ x2 ║ ForLoop ║กระจาย║
╠═══════════════╬══════╬═════════════════╬════════ ═══════╬═════════╬══════════╣
║ mOps / วินาที║179║104║ 76 ║ 81 ║28║
╠═══════════════╬══════╬═════════════════╬════════ ═══════╬═════════╬══════════╣
arr อาร์เรย์เบาบาง║YES! slic เฉพาะส่วนที่หั่น║ไม่ใช่║อาจจะ2   ║ไม่ได้║
║เก็บกระจัดกระจาย║║array (หาเรื่องที่ 1) ║║║║
╠═══════════════╬══════╬═════════════════╬════════ ═══════╬═════════╬══════════╣
║รองรับ║MSIE4║MSIE 5.5 ║ MSIE 5.5 ║ MSIE 4 ║Edge 12 ║
║ ( แหล่งที่มา ) ║NNav4║NNav 4.06 ║ NNav 4.06 ║ NNav 3 ║ MSIE  NNav ║
╠═══════════════╬══════╬═════════════════╬════════ ═══════╬═════════╬══════════╣
║การกระทำที่คล้ายอาเรย์║ไม่เพียง แต่ผลัก║ใช่! ║ใช่! ║หากมี║
array like a array ║║array (2nd ARG) ║║║iterator 1   ║
╚═══════════════╩══════╩═════════════════╩════════ ═══════╩═════════╩══════════╝
1หากวัตถุคล้ายอาร์เรย์ไม่มีคุณสมบัติSymbol.iteratorให้ลอง
  การแพร่กระจายมันจะทำให้เกิดข้อยกเว้น
2ขึ้นอยู่กับรหัส โค้ดตัวอย่างต่อไปนี้ "YES" รักษาความเป็นเบาบาง
function mergeCopyTogether(inputOne, inputTwo){
   var oneLen = inputOne.length, twoLen = inputTwo.length;
   var newArr = [], newLen = newArr.length = oneLen + twoLen;
   for (var i=0, tmp=inputOne[0]; i !== oneLen; ++i) {
        tmp = inputOne[i];
        if (tmp !== undefined || inputOne.hasOwnProperty(i)) newArr[i] = tmp;
    }
    for (var two=0; i !== newLen; ++i, ++two) {
        tmp = inputTwo[two];
        if (tmp !== undefined || inputTwo.hasOwnProperty(two)) newArr[i] = tmp;
    }
    return newArr;
}

เท่าที่เห็นข้างต้นฉันจะยืนยันว่า Concat เป็นวิธีที่จะไปสำหรับทั้งการแสดงและความสามารถในการรักษาความกระจัดกระจายของอาร์เรย์ว่าง จากนั้นสำหรับการชอบอาเรย์ (เช่น DOMNodeLists document.body.children) ฉันขอแนะนำให้ใช้ลูป for เนื่องจากเป็นทั้งตัวที่มีประสิทธิภาพมากที่สุดอันดับสองและอีกวิธีเดียวที่เก็บอาร์เรย์เบาบาง ด้านล่างเราจะไปอย่างรวดเร็วสิ่งที่มีความหมายโดยอาร์เรย์เบาบางและชอบอาร์เรย์เพื่อล้างความสับสน

𝗧𝗵𝗲𝗙𝘂𝘁𝘂𝗿𝗲

ในตอนแรกบางคนอาจคิดว่านี่เป็นความบังเอิญและในที่สุดผู้ขายเบราว์เซอร์ก็จะสามารถปรับแต่ง Array.prototype.push ให้เร็วที่สุดเพื่อเอาชนะ Array.prototype.concat ไม่ถูกต้อง! Array.prototype.concat จะเร็วขึ้นเสมอ (ตามหลักการอย่างน้อยที่สุด) เพราะมันเป็น copy-n-paste อย่างง่าย ๆ เหนือข้อมูล ด้านล่างนี้เป็นไดอะแกรมแบบ persuado-visual ที่เรียบง่ายของการใช้อาร์เรย์แบบ 32 บิต (โปรดทราบว่าการใช้งานจริงมีความซับซ้อนมากขึ้น)

ไบต์║ข้อมูลที่นี่
═════╬═══════════
0x00 ║ int nonNumericPropertiesLength = 0x00000000
0x01 ║อ้างแล้ว
0x02 ║อ้างแล้ว
0x03 ║อ้างแล้ว
ความยาว 0x00 ║ int = 0x00000001
0x01 ║อ้างแล้ว
0x02 ║อ้างแล้ว
0x03 ║อ้างแล้ว
0x00 ║ int valueIndex = 0x00000000
0x01 ║อ้างแล้ว
0x02 ║อ้างแล้ว
0x03 ║อ้างแล้ว
0x00 ║ int valueType = JS_PRIMITIVE_NUMBER
0x01 ║อ้างแล้ว
0x02 ║อ้างแล้ว
0x03 ║อ้างแล้ว
0x00 ║ uintptr_t valuePointer = 0x38d9eb60 (หรือที่ใดก็ตามที่อยู่ในหน่วยความจำ)
0x01 ║อ้างแล้ว
0x02 ║อ้างแล้ว
0x03 ║อ้างแล้ว

เท่าที่เห็นข้างต้นสิ่งที่คุณต้องทำเพื่อคัดลอกบางอย่างเช่นนั้นเกือบจะง่ายเหมือนการคัดลอกไบต์สำหรับไบต์ ด้วย Array.prototype.push.apply มันเป็นมากกว่าการคัดลอก -n-paste อย่างง่าย ๆ เหนือข้อมูล ".apply" จะต้องตรวจสอบแต่ละดัชนีในอาร์เรย์และแปลงเป็นชุดของอาร์กิวเมนต์ก่อนส่งผ่านไปยัง Array.prototype.push จากนั้น Array.prototype.push จะต้องจัดสรรหน่วยความจำเพิ่มเติมในแต่ละครั้งและ (สำหรับเบราว์เซอร์ที่ใช้งาน) อาจจะคำนวณข้อมูลการค้นหาตำแหน่งเพื่อความกระจ่าง

อีกทางเลือกหนึ่งในการคิดคือ อาร์เรย์ต้นทางหนึ่งคือกองกระดาษขนาดใหญ่ที่เย็บเข้าด้วยกัน อาร์เรย์ของแหล่งที่มาสองเป็นอีกหนึ่งกองเอกสารขนาดใหญ่ มันจะเร็วขึ้นหรือเปล่า

  1. ไปที่ร้านซื้อกระดาษให้เพียงพอเพื่อคัดลอกอาเรย์แต่ละชุด จากนั้นให้วางชุดกระดาษต้นฉบับแต่ละชุดผ่านเครื่องถ่ายเอกสารและเย็บเล่มผลสองชุดเข้าด้วยกัน
  2. ไปที่ร้านซื้อกระดาษให้เพียงพอเพื่อทำสำเนาอาร์เรย์แรกชุดแรก จากนั้นคัดลอกอาเรย์แหล่งลงในกระดาษใหม่ด้วยมือเพื่อให้แน่ใจว่าเติมลงในช่องว่างที่กระจัดกระจาย จากนั้นกลับไปที่ร้านซื้อกระดาษให้เพียงพอสำหรับอาร์เรย์แหล่งที่สอง จากนั้นไปยังอาร์เรย์แหล่งที่สองและคัดลอกในขณะที่มั่นใจว่าไม่มีช่องว่างว่างในการคัดลอก จากนั้นเย็บเล่มเอกสารที่คัดลอกทั้งหมดเข้าด้วยกัน

ในการเปรียบเทียบข้างต้นตัวเลือก # 1 หมายถึง Array.prototype.concat ในขณะที่ # 2 หมายถึง Array.prototype.push.apply ให้เราทดสอบสิ่งนี้ด้วย JSperf ที่คล้ายกันซึ่งแตกต่างกันเฉพาะในที่นี้ทดสอบวิธีการเกี่ยวกับอาร์เรย์กระจัดกระจายไม่ใช่อาร์เรย์ที่มั่นคง หนึ่งสามารถค้นหาได้ที่นี่

ดังนั้นฉันพักกรณีของฉันว่าอนาคตของประสิทธิภาพสำหรับกรณีการใช้งานเฉพาะนี้ไม่ได้อยู่ใน Array.prototype.push แต่ใน Array.prototype.concat

𝗖𝗹𝗮𝗿𝗶𝗳𝗶𝗰𝗮𝘁𝗶𝗼𝗻𝘀

𝗦𝗽𝗮𝗿𝗲𝗔𝗿𝗿𝗮𝘆𝘀

เมื่อสมาชิกบางคนของอาเรย์หายไป ตัวอย่างเช่น:

// This is just as an example. In actual code, 
// do not mix different types like this.
var mySparseArray = [];
mySparseArray[0] = "foo";
mySparseArray[10] = undefined;
mySparseArray[11] = {};
mySparseArray[12] =  10;
mySparseArray[17] = "bar";
console.log("Length:   ", mySparseArray.length);
console.log("0 in it:  ", 0 in mySparseArray);
console.log("arr[0]:   ", mySparseArray[0]);
console.log("10 in it: ", 10 in mySparseArray);
console.log("arr[10]   ", mySparseArray[10]);
console.log("20 in it: ", 20 in mySparseArray);
console.log("arr[20]:  ", mySparseArray[20]);

อีกวิธีหนึ่งคือ javascript ช่วยให้คุณสามารถเริ่มต้นอาร์เรย์ว่างได้อย่างง่ายดาย

var mySparseArray = ["foo",,,,,,,,,,undefined,{},10,,,,,"bar"];

𝗔𝗿𝗿𝗮𝘆-𝗟𝗶𝗸𝗲𝘀

อาร์เรย์เหมือนเป็นวัตถุที่มีlengthคุณสมบัติอย่างน้อยแต่ไม่ได้เริ่มต้นด้วยnew Arrayหรือ[]; ตัวอย่างเช่นวัตถุด้านล่างถูกจัดประเภทเป็นเหมือนอาร์เรย์

{0: "foo", 1: "bar", ความยาว: 2}
document.body.children
ใหม่ Uint8Array (3)
  • นี่เป็นเหมือนอาร์เรย์เนื่องจากแม้ว่าจะเป็นอาร์เรย์ (n) (พิมพ์) การบังคับให้อาร์เรย์เปลี่ยนโครงสร้างตัวสร้าง
(function () {return อาร์กิวเมนต์}) ()

สังเกตสิ่งที่เกิดขึ้นโดยใช้วิธีการที่บังคับให้อาร์เรย์ชอบเข้าไปในอาร์เรย์เช่นชิ้น

  • หมายเหตุ:มันเป็นวิธีปฏิบัติที่ไม่ดีในการเรียกใช้ slice บนอาร์กิวเมนต์ของฟังก์ชันเนื่องจากประสิทธิภาพ

สังเกตสิ่งที่เกิดขึ้นโดยใช้วิธีที่ไม่บีบบังคับอาร์เรย์ - ชอบเข้าไปในอาร์เรย์เหมือน concat


9

ด้วย JavaScript ES6 คุณสามารถใช้ตัวดำเนินการ ... เป็นตัวดำเนินการสเปรดซึ่งจะแปลงอาร์เรย์เป็นค่า จากนั้นคุณสามารถทำสิ่งนี้:

const myArray = [1,2,3,4,5];
const moreData = [6,7,8,9,10];

const newArray = [
  ...myArray,
  ...moreData,
];

ในขณะที่ไวยากรณ์มีความรัดกุมฉันไม่ทราบวิธีการทำงานภายในและสิ่งที่เกี่ยวข้องกับประสิทธิภาพการทำงานในอาร์เรย์ขนาดใหญ่


2
หากคุณดูว่า babel แปลงอย่างไรคุณจะเห็นว่าไม่ควรช้ากว่าการใช้Array.push.applyเทคนิค
emil.c

1
@ JackGiffin ฉันแค่พูดถึงสิ่งที่ไรอันพูดถึงว่าเขาไม่รู้ว่ามันทำงานอย่างไรภายในและสิ่งที่เป็นนัยเกี่ยวกับประสิทธิภาพฉันไม่ได้แนะนำวิธีการนี้จริงๆ ไม่ว่าในกรณีใดคุณทำได้ดีมากในคำตอบของคุณการวิจัยที่ดีมันดีเสมอที่จะรู้รายละเอียดดังกล่าว
emil.c

9

นี่คือวิธี ES6

var newArray = [];
let dataArray1 = [1,2,3,4]
let dataArray2 = [5,6,7,8]
newArray = [...dataArray1, ...dataArray2]
console.log(newArray)

วิธีการดังกล่าวเป็นวิธีที่ดีสำหรับกรณีส่วนใหญ่และกรณีที่ไม่ได้โปรดพิจารณาconcatเช่นคุณมีหลายแสนรายการในอาร์เรย์

    let dataArray1 = [1,2,3,4]
    let dataArray2 = [5,6,7,8]
    let newArray = dataArray1.concat(dataArray2);
    console.log(newArray)


8

มีจำนวนของคำตอบที่พูดคุยเกี่ยวกับการเป็นArray.prototype.push.apply นี่คือตัวอย่างที่ชัดเจน:

var dataArray1 = [1, 2];
var dataArray2 = [3, 4, 5];
var newArray = [ ];
Array.prototype.push.apply(newArray, dataArray1); // newArray = [1, 2]
Array.prototype.push.apply(newArray, dataArray2); // newArray = [1, 2, 3, 4, 5]
console.log(JSON.stringify(newArray)); // Outputs: [1, 2, 3, 4, 5]

หากคุณมีไวยากรณ์ ES6:

var dataArray1 = [1, 2];
var dataArray2 = [3, 4, 5];
var newArray = [ ];
newArray.push(...dataArray1); // newArray = [1, 2]
newArray.push(...dataArray2); // newArray = [1, 2, 3, 4, 5]
console.log(JSON.stringify(newArray)); // Outputs: [1, 2, 3, 4, 5]


4

หากคุณต้องการแก้ไขอาเรย์ดั้งเดิมคุณสามารถกระจายและกด:

var source = [1, 2, 3];
var range = [5, 6, 7];
var length = source.push(...range);

console.log(source); // [ 1, 2, 3, 5, 6, 7 ]
console.log(length); // 6

หากคุณต้องการให้แน่ใจว่ารายการประเภทเดียวกันเท่านั้นไปในsourceอาร์เรย์ (ตัวอย่างเช่นไม่ได้ผสมตัวเลขและสตริง) จากนั้นใช้ TypeScript

/**
 * Adds the items of the specified range array to the end of the source array.
 * Use this function to make sure only items of the same type go in the source array.
 */
function addRange<T>(source: T[], range: T[]) {
    source.push(...range);
}

2

เรามีสองชุด a และ b โค้ดที่ทำที่นี่คืออาร์เรย์ค่าจะถูกผลักเข้าไปในอาร์เรย์ b

let a = [2, 4, 6, 8, 9, 15]

function transform(a) {
    let b = ['4', '16', '64']
    a.forEach(function(e) {
        b.push(e.toString());
    });
    return b;
}

transform(a)

[ '4', '16', '64', '2', '4', '6', '8', '9', '15' ]

1
โปรดอย่าเพิ่งโพสต์รหัสเป็นคำตอบ อธิบายสิ่งที่รหัสทำและวิธีแก้ปัญหา
Patrick Hund


-2

แทนที่จะใช้ฟังก์ชัน push () ใช้ฟังก์ชัน concat สำหรับ IE ตัวอย่าง,

var a=a.concat(a,new Array('amin'));

1
ทั้งสองเข้ากันได้กับ IE อย่างมาก
Jack Giffin

-3

Тhisเป็นรหัสทำงานและทำงานได้ดี:

var els = document.getElementsByTagName('input'), i;
var invnum = new Array();
var k = els.length;
for(i = 0; i < k; i++){invnum.push(new Array(els[i].id,els[i].value))}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.