นี่คือบทความง่ายๆเกี่ยวกับเคล็ดลับในการใช้อาร์เรย์ 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,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`for (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, รายการ) {coll.push (รายการ); return coll;}, a); a; // [1,2,3,4,5,6,7,7,8,9, "foo", "bar", "baz", "bam", "bun", "fun"] // หรือ `a` เป็น` b`: b = a.reduceright (ฟังก์ชั่น (coll, รายการ) // [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)); -เดี๋ยวก่อนความสามารถในการอ่านของเราได้ย้อนกลับไป เช่นนั้นมันอาจแย่ลงเรื่อย ๆ
ข้างต้นเป็นเรื่องเกี่ยวกับบทความนี้ฉันหวังว่ามันจะเป็นประโยชน์สำหรับทุกคนในการเรียนรู้การเขียนโปรแกรม JavaScript