รูปแบบตัวเลขที่เรียกว่าคือการเพิ่มเครื่องหมายจุลภาคระหว่างทุก ๆ สามหลักที่เริ่มต้นจากตัวเลขหลักเดียว ตัวอย่างเช่น "10,000" เพื่อตอบสนองความต้องการนี้ฉันเริ่มเขียนฟังก์ชั่นเช่นนี้:
การคัดลอกรหัสมีดังนี้:
// วิธี 1
ฟังก์ชั่น tothings (num) {
var result = [], counter = 0;
num = (num || 0) .toString (). แยก ('');
สำหรับ (var i = num.length-1; i> = 0; i--) {
เคาน์เตอร์ ++;
result.unshift (num [i]);
if (! (counter % 3) && i! = 0) {result.unshift (','); -
-
return result.oin ('');
-
กระบวนการดำเนินการของวิธีการหนึ่งคือการแปลงตัวเลขเป็นสตริงแบ่งเป็นอาร์เรย์แล้วเริ่มจากจุดสิ้นสุดให้แทรกองค์ประกอบในอาร์เรย์ไปยังจุดเริ่มต้นของอาร์เรย์ใหม่ (ผลลัพธ์) ทุกครั้งที่มีการแทรกองค์ประกอบตัวนับจะนับจำนวน (เพิ่ม 1) เมื่อเคาน์เตอร์เป็นคูณของ 3 จุลภาคจะถูกแทรก แต่ระวังว่าไม่มีเครื่องหมายจุลภาคที่จะเริ่มต้น (เมื่อฉันคือ 0) ในที่สุดผลลัพธ์จะได้รับโดยการเรียกใช้วิธีการเข้าร่วมของอาร์เรย์ใหม่
วิธีนี้ชัดเจนและเข้าใจง่ายขึ้นและมันก็ใช้ในโครงการสักพัก แต่สัญชาตญาณบอกฉันว่ามันทำงานได้ไม่ดี
วิธี 2 - เวอร์ชันสตริงของวิธี 1
การคัดลอกรหัสมีดังนี้:
// วิธี 2
ฟังก์ชั่น tothings (num) {
var result = '', counter = 0;
num = (num || 0) .toString ();
สำหรับ (var i = num.length-1; i> = 0; i--) {
เคาน์เตอร์ ++;
ผลลัพธ์ = num.charat (i) + ผลลัพธ์;
if (! (counter % 3) && i! = 0) {result = ',' + ผลลัพธ์; -
-
ผลการกลับมา;
-
วิธีที่ 2 เป็นรุ่นที่ได้รับการปรับปรุงให้ดีขึ้น 1 มันไม่ได้แบ่งสตริงเป็นอาร์เรย์และทำงานบนสตริงเสมอ
วิธีที่ 3 - ลูปตรงกับตัวเลขสามตัวในตอนท้าย
การคัดลอกรหัสมีดังนี้:
// วิธี 3
ฟังก์ชั่น tothings (num) {
var num = (num || 0) .toString (), re = // d {3} $/, result = '';
ในขณะที่ (re.test (num)) {
ผลลัพธ์ = regexp.lastmatch + ผลลัพธ์;
if (num! == regexp.lastmatch) {
ผลลัพธ์ = ',' + ผลลัพธ์;
num = regexp.leftcontext;
} อื่น {
num = '';
หยุดพัก;
-
-
if (num) {result = num + ผลลัพธ์; -
ผลการกลับมา;
-
วิธีที่ 3 เป็นอัลกอริทึมที่แตกต่างอย่างสิ้นเชิง ตัวเลขสามตัวในตอนท้ายจะถูกจับคู่ผ่านลูปนิพจน์ทั่วไป ทุกครั้งที่มีการจับคู่การจับคู่เครื่องหมายจุลภาคและเนื้อหาการจับคู่จะถูกแทรกที่จุดเริ่มต้นของสตริงผลลัพธ์และจากนั้นเป้าหมายการจับคู่ (NUM) จะถูกกำหนดให้กับเนื้อหาที่ยังไม่ตรงกัน (regexp.leftContext) นอกจากนี้โปรดทราบ:
1. หากจำนวนตัวเลขเป็นแบบหลายตัวของ 3 การจับคู่สุดท้ายจะต้องเป็นตัวเลขสามตัว แต่ไม่จำเป็นต้องเพิ่มเครื่องหมายจุลภาคก่อนตัวเลขสามตัวแรก
2. หากจำนวนบิตของตัวเลขไม่ใช่มัลติของ 3 ตัวแปร NUM จะมีหมายเลข 1 ถึง 2 ที่เหลืออยู่ในตอนท้าย หลังจากลูปตัวเลขที่เหลือควรถูกแทรกที่จุดเริ่มต้นของสตริงผลลัพธ์
แม้ว่าวิธีการสามจะลดจำนวนลูป (สามอักขระจะถูกประมวลผลในแต่ละครั้ง) การบริโภคจะเพิ่มขึ้นในระดับหนึ่งเนื่องจากการใช้การแสดงออกปกติ
วิธี 4 - เวอร์ชันสตริงของวิธี 3
การคัดลอกรหัสมีดังนี้:
// วิธี 4
ฟังก์ชั่น tothings (num) {
var num = (num || 0) .toString (), result = '';
ในขณะที่ (num.length> 3) {
result = ',' + num.slice (-3) + ผลลัพธ์;
num = num.slice (0, num.length - 3);
-
if (num) {result = num + ผลลัพธ์; -
ผลการกลับมา;
-
ในความเป็นจริงฟังก์ชั่นของการสกัดกั้นอักขระสามตัวสุดท้ายสามารถทำได้ผ่านชิ้นส่วนย่อยหรือวิธีการย่อยของประเภทสตริง สิ่งนี้หลีกเลี่ยงการแสดงออกปกติ
วิธีที่ 5 - วิธีการรวมและการบรรจบกัน
การคัดลอกรหัสมีดังนี้:
// วิธี 5
ฟังก์ชั่น tothings (num) {
var num = (num || 0) .toString (), temp = num.length % 3;
สลับ (อุณหภูมิ) {
กรณีที่ 1:
num = '00' + num;
หยุดพัก;
กรณีที่ 2:
num = '0' + num;
หยุดพัก;
-
return num.match (// d {3}/g) .join (',') แทนที่ (/^0+/, '');
-
ขั้นแรกให้ทำจำนวนตัวเลขเป็นทวีคูณของ 3 ตัดเป็นกลุ่มของตัวเลขสามตัวผ่านการแสดงออกปกติจากนั้นเพิ่มเครื่องหมายจุลภาคผ่านวิธีการเข้าร่วมและในที่สุดก็ลบส่วนประกอบ 0
วิธีที่ 6 - วิธีขี้เกียจ
การคัดลอกรหัสมีดังนี้:
// วิธีที่ 6
ฟังก์ชั่น tothings (num) {
return (num || 0) .toString (). แทนที่ (/(/d) (? = (?:/d {3})+$)/g, '$ 1,');
-
ฉันมักจะรู้สึกว่าการจัดรูปแบบนี้สามารถทำได้โดยการเปลี่ยนนิพจน์ทั่วไป แต่ฉันต้องใช้การยืนยันและวิธีการเขียนอื่น ๆ แต่ฉันไม่คุ้นเคยกับส่วนนี้ หลังจาก Googled ฉันพบนิพจน์ทั่วไปซึ่งอาจเป็นการใช้งานรหัสที่สั้นที่สุด
ผลการทดสอบ
| ตัวเลข | ใช้เวลากับ 5,000 ครั้ง (MS) | |||||
|---|---|---|---|---|---|---|
| วิธีที่ 1 | วิธีที่ 2 | วิธีที่ 3 | วิธีที่ 4 | วิธีที่ 5 | วิธีที่ 6 | |
| 1 | 4 | 1 | 3 | 1 | 14 | 2 |
| 10 | 14 | 1 | 3 | 0 | 7 | 2 |
| 100 | 12 | 1 | 2 | 4 | 5 | 3 |
| 1,000 | 13 | 2 | 3 | 2 | 9 | 5 |
| 10,000 | ยี่สิบเอ็ด | 4 | 3 | 1 | 6 | 3 |
| 100000 | ยี่สิบเอ็ด | 3 | 2 | 1 | 5 | 6 |
การเปรียบเทียบที่แข็งแกร่งระหว่างวิธีการที่ 1 และวิธีที่ 2 แสดงให้เห็นว่าประสิทธิภาพของการทำงานของสตริงนั้นสูงกว่าการดำเนินการอาร์เรย์มาก ผลการทดสอบของวิธีการ 6 บอกเราว่าความยาวของรหัสไม่มีส่วนเกี่ยวข้องกับประสิทธิภาพ วิธีที่ 4 มีประสิทธิภาพที่ครอบคลุมที่สุด (แต่ทำไม NUM จึงลดลงเมื่อ 100 NUM ไม่สามารถแก้ไขได้จริง ๆ ) เหตุผลหลักคือ:
1. เปรียบเทียบวิธีการ 1 และ 2 ใช้ 3 ตัวอักษรแทน 1 อักขระทุกครั้งเพื่อลดจำนวนลูป
2. วิธีการเปรียบเทียบ 3, 5 และ 6 โดยไม่ต้องใช้การแสดงออกปกติลดการบริโภค
ในที่สุดฉันเลือกวิธีการสี่เป็นโซลูชันการเพิ่มประสิทธิภาพขั้นสุดท้าย ผู้อ่านสามารถแสดงความคิดเห็นหากพวกเขามีวิธีการใช้งานหรือคำแนะนำที่ดีกว่า