นี่คือบทความง่ายๆเกี่ยวกับเคล็ดลับในการใช้อาร์เรย์ JavaScript เราจะใช้วิธีการที่แตกต่างกันเพื่อรวม/ผสานอาร์เรย์ JS สองตัวรวมทั้งหารือเกี่ยวกับข้อดี/ข้อเสียของแต่ละวิธี
ลองพิจารณาสถานการณ์ต่อไปนี้ก่อน:
การคัดลอกรหัสมีดังนี้:
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var b = ["foo", "bar", "baz", "bam", "bun", "fun"];
เห็นได้ชัดว่าผลลัพธ์การรวมกันที่ง่ายที่สุดควรเป็น:
การคัดลอกรหัสมีดังนี้:
-
1, 2, 3, 4, 5, 6, 7, 8, 9,
"foo", "bar", "baz", "bam" "bun", "fun"
-
concat (.. )
นี่เป็นวิธีปฏิบัติที่พบบ่อยที่สุด:
การคัดลอกรหัสมีดังนี้:
var c = a.concat (b);
a; // [1,2,3,4,5,6,7,8,9]
B; // ["foo", "bar", "baz", "bam", "bun", "fun"]
C; // [1,2,3,4,5,6,7,7,8,9, "foo", "bar", "baz", "bam", "bun", "fun"]
อย่างที่คุณเห็น C เป็นอาร์เรย์ใหม่เอี่ยมที่แสดงถึงการรวมกันของสองอาร์เรย์ A และ B และเก็บค่าคงที่ A และ B เรียบง่าย?
แต่ถ้า A มี 10,000 องค์ประกอบและ B มี 10,000 องค์ประกอบ? C จะมีองค์ประกอบ 20,000 รายการดังนั้นการใช้หน่วยความจำของ A และ B จะเพิ่มเป็นสองเท่า
"ไม่มีปัญหา!" คุณพูด ปล่อยให้พวกเขาเก็บขยะตั้งค่า A และ B เป็นโมฆะปัญหาได้รับการแก้ไข!
a = b = null; // 'A' และ 'B' ถูกรีไซเคิล
ฮิฮิ สำหรับอาร์เรย์ขนาดเล็กที่มีเพียงไม่กี่องค์ประกอบนี่เป็นเรื่องปกติ แต่สำหรับอาร์เรย์ขนาดใหญ่หรือระบบที่มีหน่วยความจำที่ จำกัด กระบวนการนี้จะต้องทำซ้ำบ่อยครั้งจริง ๆ มันมีการปรับปรุงมากมาย
การแทรกลูป
ตกลงลองคัดลอกเนื้อหาของอาร์เรย์หนึ่งไปอีกอันโดยใช้: อาร์เรย์#push (.. )
การคัดลอกรหัสมีดังนี้:
// `b` ไปที่` a '
สำหรับ (var i = 0; i <b.length; i ++) {
A.push (b [i]);
-
a; // [1,2,3,4,5,6,7,7,8,9, "foo", "bar", "baz", "bam", "bun", "fun"]
b = null;
ตอนนี้ Array A มีเนื้อหาของอาร์เรย์ b
ดูเหมือนว่าจะมีรอยเท้าหน่วยความจำที่ดีขึ้น
แต่ถ้าอาร์เรย์ A มีขนาดเล็กกว่าล่ะ? ด้วยเหตุผลหน่วยความจำและความเร็วคุณอาจต้องการให้เล็กลงด้านหน้า B, ไม่มีปัญหาเพียงแค่เปลี่ยน push (.. ) เป็น unshift (.. ):
การคัดลอกรหัสมีดังนี้:
// `a` into` b`:
สำหรับ (var i = a.length-1; i> = 0; i--) {
B.Unshift (A [i]);
-
B; // [1,2,3,4,5,6,7,7,8,9, "foo", "bar", "baz", "bam", "bun", "fun"]
ทักษะการใช้งาน
อย่างไรก็ตามการวนรอบนั้นน่าเกลียดและยากที่จะรักษา เราทำได้ดีกว่านี้ไหม
นี่เป็นความพยายามครั้งแรกของเราโดยใช้อาร์เรย์#ลด:
การคัดลอกรหัสมีดังนี้:
// `b` ไปที่` a`:
A = B.Reduce (ฟังก์ชั่น (coll, item) {
coll.push (รายการ);
กลับมาคอล;
}, a);
a; // [1,2,3,4,5,6,7,7,8,9, "foo", "bar", "baz", "bam", "bun", "fun"]
// หรือ `a` into` b`:
B = A.Reduceright (ฟังก์ชั่น (coll, item) {
coll.unshift (รายการ);
กลับมาคอล;
}, b);
B; // [1,2,3,4,5,6,7,7,8,9, "foo", "bar", "baz", "bam", "bun", "fun"]
อาร์เรย์#ลด (.. ) และอาร์เรย์#reduceright (.. ) เป็นสิ่งที่ดี แต่มันค่อนข้างซุ่มซ่ามเล็กน้อย ฟังก์ชั่นลูกศรของ ES6 => จะลดปริมาณของรหัส แต่ก็ยังต้องใช้ฟังก์ชันและแต่ละองค์ประกอบจะต้องเรียกครั้งเดียวซึ่งไม่สมบูรณ์แบบ
แล้วเรื่องนี้:
การคัดลอกรหัสมีดังนี้:
// `b` ไปที่` a`:
A.push.apply (a, b);
a; // [1,2,3,4,5,6,7,7,8,9, "foo", "bar", "baz", "bam", "bun", "fun"]
// หรือ `a` into` b`:
B.Unshift.Apply (B, A);
B; // [1,2,3,4,5,6,7,7,8,9, "foo", "bar", "baz", "bam", "bun", "fun"]
ที่นี่เป็นสถานที่ที่ดีกว่ามาก? โดยเฉพาะอย่างยิ่งเนื่องจากวิธีการไม่เปลี่ยน (.. ) ไม่จำเป็นต้องกังวลเกี่ยวกับการเรียงลำดับย้อนกลับก่อนหน้านี้ที่นี่ การดำเนินการพูดของ ES6 จะสวยงามกว่า: A.push (... b) หรือ B.Unshift (... A
ขีดจำกัดความยาวสูงสุดสำหรับอาร์เรย์
ปัญหาที่สำคัญครั้งแรกคือการใช้หน่วยความจำเป็นสองเท่า (เพียงชั่วคราวแน่นอน!) โดยทั่วไปแล้วการคัดลอกองค์ประกอบลงในสแต็กผ่านการเรียกใช้ฟังก์ชั่น นอกจากนี้เครื่องยนต์ JS ที่แตกต่างกันมีข้อ จำกัด เกี่ยวกับความยาวของข้อมูลการคัดลอก
ดังนั้นหากอาร์เรย์มีองค์ประกอบล้านคุณจะเกินขีด จำกัด ที่ผลักดัน (... ) หรือ Unshift (... ) อนุญาตให้มีการโทร อนิจจามันจะทำงานได้อย่างยอดเยี่ยมในการจัดการองค์ประกอบหลายพันองค์ประกอบ แต่คุณต้องระวังไม่ให้เกินขีดจำกัดความยาวที่เหมาะสม
หมายเหตุ: คุณสามารถลอง Splice (... ) ซึ่งมีปัญหานี้เช่น push (... ) และ unshift (... )
มีวิธีหลีกเลี่ยงขีดจำกัดความยาวสูงสุดนี้
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น compineInto (a, b) {
var len = a.length;
สำหรับ (var i = 0; i <len; i = i+5000) {
b.unshift.apply (b, a.slice (i, i+5000));
-
-
เดี๋ยวก่อนความสามารถในการอ่านของเราได้ย้อนกลับไป นั่นคือมันอาจจะแย่ลงเรื่อย ๆ ฮ่าฮ่า