วิธีที่มีประสิทธิภาพที่สุดในการสร้างอาเรย์ JavaScript ที่เต็มไปด้วยศูนย์?
วิธีที่มีประสิทธิภาพที่สุดในการสร้างอาร์เรย์ที่เต็มไปด้วยศูนย์และมีความยาวตามต้องการใน JavaScript คืออะไร?
คำตอบ #1
ES6 แนะนำ Array.prototype.fill สามารถใช้ได้ดังนี้:
new Array(len).fill(0);
ไม่แน่ใจว่ามันเร็วหรือเปล่า แต่ฉันชอบเพราะมันสั้นและบรรยายตัวเองได้
มันยังไม่ได้อยู่ใน IE (ตรวจสอบความเข้ากันได้) แต่มีโพลีฟิลล์ให้ใช้งานอยู่
คำตอบ #2
แม้ว่านี่จะเป็นกระทู้เก่า แต่ฉันอยากจะเพิ่มความคิดเห็นของฉันลงไป ไม่แน่ใจว่ามันช้า/เร็วแค่ไหน แต่มันเป็นบรรทัดเดียวที่เร็ว นี่คือสิ่งที่ฉันทำ:
ถ้าฉันต้องการกรอกล่วงหน้าด้วยตัวเลข:
Array.apply(null, Array(5)).map(Number.prototype.valueOf,0);
// [0, 0, 0, 0, 0]
ถ้าฉันต้องการกรอกล่วงหน้าด้วยสตริง:
Array.apply(null, Array(3)).map(String.prototype.valueOf,"hi")
// ["hi", "hi", "hi"]
คำตอบอื่นๆ ได้แนะนำว่า:
new Array(5+1).join('0').split('')
// ["0", "0", "0", "0", "0"]
แต่ถ้าคุณต้องการ 0 (ตัวเลข) และไม่ใช่ "0" (ศูนย์ในสตริง) คุณสามารถทำได้ดังนี้:
new Array(5+1).join('0').split('').map(parseFloat)
// [0, 0, 0, 0, 0]
คำตอบ #3
โดยย่อ
วิธีแก้ปัญหาที่เร็วที่สุด:
let a = new Array(n); for (let i=0; i<n; ++i) a[i] = 0;
วิธีแก้ปัญหาที่สั้นที่สุด (สะดวก) (ช้ากว่า 3 เท่าสำหรับอาร์เรย์ขนาดเล็ก, ช้ากว่านิดหน่อยสำหรับอาร์เรย์ขนาดใหญ่ (ช้าที่สุดใน Firefox))
Array(n).fill(0)
รายละเอียด
วันนี้ 2020.06.09 ฉันทำการทดสอบบน macOS High Sierra 10.13.6 บนเบราว์เซอร์ Chrome 83.0, Firefox 77.0, และ Safari 13.1 ฉันทดสอบโซลูชันที่เลือกสำหรับสองกรณีทดสอบ
- อาเรย์ขนาดเล็ก - มี 10 องค์ประกอบ - คุณสามารถทดสอบได้ที่นี่
- อาเรย์ขนาดใหญ่ - มี 1 ล้านสมาชิก - คุณสามารถทดสอบที่นี่
ข้อสรุป
- วิธีแก้ปัญหาที่อิงตาม
new Array(n)+for(N) เป็นวิธีแก้ปัญหาที่เร็วที่สุดสำหรับอาร์เรย์ขนาดเล็กและอาร์เรย์ขนาดใหญ่ (ยกเว้น Chrome แต่ก็ยังเร็วมากที่นั่น) และแนะนำให้ใช้เป็นวิธีแก้ปัญหาข้ามเบราว์เซอร์ที่เร็ว - วิธีแก้ปัญหาที่อิงตาม
new Float32Array(n)(I) จะส่งกลับอาเรย์ที่ไม่ปกติ (เช่น คุณไม่สามารถเรียกใช้push(..)กับมันได้) ดังนั้นฉันจึงไม่เปรียบเทียบผลลัพธ์กับวิธีแก้ปัญหาอื่น ๆ - อย่างไรก็ตาม วิธีแก้ปัญหานี้เร็วกว่าวิธีแก้ปัญหาอื่นประมาณ 10-20 เท่าสำหรับอาเรย์ขนาดใหญ่ในทุกเบราว์เซอร์ - โซลูชันที่อิงตาม
for(L,M,N,O) มีความเร็วสำหรับอาร์เรย์ขนาดเล็ก - โซลูชันที่อิงกับ
fill(B,C) ทำงานได้เร็วบน Chrome และ Safari แต่กลับช้าที่สุดอย่างน่าประหลาดใจบน Firefox สำหรับอาร์เรย์ขนาดใหญ่ สำหรับอาร์เรย์ขนาดเล็กจะทำงานได้ค่อนข้างเร็วปานกลาง วิธีแก้ปัญหาที่อิงตาม
Array.apply(P) จะเกิดข้อผิดพลาดสำหรับอาร์เรย์ขนาดใหญ่function P(n) { return Array.apply(null, Array(n)).map(Number.prototype.valueOf,0); } try { P(1000000); } catch(e) { console.error(e.message); }
โค้ดและตัวอย่าง
โค้ดด้านล่างแสดงวิธีแก้ปัญหาที่ใช้ในการวัด
function A(n) {
return [...new Array(n)].fill(0);
}
function B(n) {
return new Array(n).fill(0);
}
function C(n) {
return Array(n).fill(0);
}
function D(n) {
return Array.from({length: n}, () => 0);
}
function E(n) {
return [...new Array(n)].map(x => 0);
}
// arrays with type
function F(n) {
return Array.from(new Int32Array(n));
}
function G(n) {
return Array.from(new Float32Array(n));
}
function H(n) {
return Array.from(new Float64Array(n)); // needs 2x more memory than float32
}
function I(n) {
return new Float32Array(n); // this is not typical array
}
function J(n) {
return [].slice.apply(new Float32Array(n));
}
// Based on for
function K(n) {
let a = [];
a.length = n;
let i = 0;
while (i < n) {
a[i] = 0;
i++;
}
return a;
}
function L(n) {
let a=[]; for(let i=0; i<n; i++) a[i]=0;
return a;
}
function M(n) {
let a=[]; for(let i=0; i<n; i++) a.push(0);
return a;
}
function N(n) {
let a = new Array(n); for (let i=0; i<n; ++i) a[i] = 0;
return a;
}
function O(n) {
let a = new Array(n); for (let i=n; i--;) a[i] = 0;
return a;
}
// other
function P(n) {
return Array.apply(null, Array(n)).map(Number.prototype.valueOf,0);
}
function Q(n) {
return "0".repeat( n ).split("").map( parseFloat );
}
function R(n) {
return new Array(n+1).join('0').split('').map(parseFloat)
}
// ---------
// TEST
// ---------
[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R].forEach(f => {
let a = f(10);
console.log(`${f.name} length=${a.length}, arr[0]=${a[0]}, arr[9]=${a[9]}`)
});This snippets only present used codesตัวอย่างผลลัพธ์สำหรับ Chrome:
คำตอบ #4
วิธีที่สง่างามในการเติมอาร์เรย์ด้วยค่าที่คำนวณล่วงหน้า
นี่คือวิธีอีกวิธีหนึ่งในการทำด้วย ES6 ที่ยังไม่มีใครพูดถึงจนถึงตอนนี้:
> Array.from(Array(3), () => 0)
< [0, 0, 0]
มันทำงานโดยการส่งฟังก์ชันแมปเป็นพารามิเตอร์ตัวที่สองของ Array.from
ในตัวอย่างด้านบน พารามิเตอร์ตัวแรกจะจัดสรรอาร์เรย์ที่มี 3 ตำแหน่งซึ่งเต็มไปด้วยค่า undefined และจากนั้นฟังก์ชันแลมบ์ดาจะแมปแต่ละอันไปยังค่า 0
แม้ว่า Array(len).fill(0) จะสั้นกว่า แต่ก็ใช้ไม่ได้ถ้าคุณจำเป็นต้องเติมอาร์เรย์โดยทำการคำนวณบางอย่างก่อน (ฉันรู้ว่าคำถามไม่ได้ถามถึงเรื่องนี้ แต่หลายคนก็มาหาสิ่งนี้ที่นี่)
ตัวอย่างเช่น หากคุณต้องการอาร์เรย์ที่มีตัวเลขสุ่ม 10 ตัว:
> Array.from(Array(10), () => Math.floor(10 * Math.random()))
< [3, 6, 8, 1, 9, 3, 0, 6, 7, 1]
มันกระชับกว่า (และสง่างามกว่า) เมื่อเทียบกับสิ่งที่เทียบเท่า
const numbers = Array(10);
for (let i = 0; i < numbers.length; i++) {
numbers[i] = Math.round(10 * Math.random());
}
วิธีนี้ยังสามารถใช้สร้างลำดับของตัวเลขได้โดยใช้ประโยชน์จากพารามิเตอร์ดัชนีที่ให้มาในฟังก์ชัน callback:
> Array.from(Array(10), (d, i) => i)
< [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
คำตอบพิเศษ: เติมอาเรย์โดยใช้ String repeat()
เนื่องจากคำตอบนี้ได้รับความสนใจมาก ผมจึงอยากจะแสดงเคล็ดลับเจ๋ง ๆ นี้ด้วย แม้ว่าจะไม่ค่อยมีประโยชน์เท่าคำตอบหลักของผม แต่จะขอแนะนำวิธี repeat() ของ String ที่ยังไม่ค่อยมีใครรู้จัก แต่มีประโยชน์มาก นี่คือเคล็ดลับ:
> "?".repeat(10).split("").map(() => Math.floor(10 * Math.random()))
< [5, 6, 3, 5, 0, 8, 2, 7, 4, 1]
เจ๋งใช่ไหม? repeat() เป็นเมธอดที่มีประโยชน์มากในการสร้างสตริงที่เป็นการซ้ำของสตริงต้นฉบับในจำนวนครั้งที่กำหนด หลังจากนั้น split() จะสร้างอาร์เรย์ให้เรา ซึ่งจากนั้นจะถูก map() ไปยังค่าที่เราต้องการ แบ่งออกเป็นขั้นตอนดังนี้:
> "?".repeat(10)
< "??????????"
> "?".repeat(10).split("")
< ["?", "?", "?", "?", "?", "?", "?", "?", "?", "?"]
> "?".repeat(10).split("").map(() => Math.floor(10 * Math.random()))
< [5, 6, 3, 5, 0, 8, 2, 7, 4, 1]
คำตอบ #5
วิธี fill ของ ES 6 ที่ได้กล่าวถึงแล้วจัดการเรื่องนี้ได้ดีมาก เบราว์เซอร์สำหรับเดสก์ท็อปสมัยใหม่ส่วนใหญ่รองรับเมธอดของ Array prototype ที่จำเป็นในปัจจุบันแล้ว (Chromium, FF, Edge และ Safari) [1] คุณสามารถดูรายละเอียดเพิ่มเติมได้ที่ MDN ตัวอย่างการใช้งานง่าย ๆ คือ
a = new Array(10).fill(0);
ด้วยการสนับสนุนเบราว์เซอร์ในปัจจุบัน คุณควรระมัดระวังในการใช้สิ่งนี้ เว้นแต่ว่าคุณแน่ใจว่าผู้ชมของคุณใช้เบราว์เซอร์เดสก์ท็อปสมัยใหม่
คำตอบ #6
หมายเหตุเพิ่มเติม สิงหาคม 2013 อัปเดต กุมภาพันธ์ 2015: คำตอบด้านล่างจากปี 2009 เกี่ยวข้องกับประเภท Array ทั่วไปของ JavaScript ซึ่งไม่ได้เกี่ยวข้องกับอาเรย์ typed ใหม่ที่กำหนดใน ES2015 [และสามารถใช้ได้ในหลายเบราว์เซอร์ตอนนี้] เช่น Int32Array และอื่นๆ นอกจากนี้ โปรดทราบว่า ES2015 เพิ่มเมธอด fill ทั้งใน Arrays และ typed arrays ซึ่งน่าจะเป็นวิธีที่มีประสิทธิภาพที่สุดในการเติมข้อมูลให้กับพวกมัน...
กับภาษาส่วนใหญ่ จะเป็นการจัดสรรล่วงหน้า แล้วเติมศูนย์ เช่นนี้:
function newFilledArray(len, val) {
var rv = new Array(len);
while (--len >= 0) {
rv[len] = val;
}
return rv;
}
แต่ อาร์เรย์ใน JavaScript จริง ๆ แล้วไม่ใช่อาร์เรย์ พวกมันเป็นแผนที่คีย์/ค่า เช่นเดียวกับอ็อบเจ็กต์ JavaScript อื่น ๆ ดังนั้นจึงไม่มีการ "จัดสรรล่วงหน้า" ที่ต้องทำ (การตั้งความยาวไม่ได้จัดสรรช่องสำหรับเติมให้ครบจำนวน) และก็ไม่มีเหตุผลที่จะเชื่อว่าประโยชน์ของการนับลงจนถึงศูนย์ (ซึ่งเป็นเพียงเพื่อทำให้การเปรียบเทียบในลูปเร็วขึ้น) จะไม่ถูกลบล้างด้วยการเพิ่มคีย์ในลำดับย้อนกลับเมื่อการใช้งานอาจได้เพิ่มประสิทธิภาพการจัดการคีย์ที่เกี่ยวข้องกับอาร์เรย์โดยสมมติว่าปกติคุณจะทำพวกมันตามลำดับ
ในความเป็นจริง Matthew Crumley ชี้ให้เห็นว่าการนับถอยหลังก็ชัดเจนว่าสูงกว่าในการใช้ Firefox เมื่อเทียบกับการนับขึ้น ซึ่งเป็นผลลัพธ์ที่ผมสามารถยืนยันได้ — มันเป็นเพราะส่วนของอาร์เรย์ (การวนลูปลงถึงศูนย์นั้นยังเร็วกว่าการวนลูปขึ้นไปจนถึงขีดจำกัดในตัวแปร) เห็นได้ชัดว่าการเพิ่มองค์ประกอบลงในอาร์เรย์ในลำดับย้อนกลับเป็นการทำงานที่ช้าบน Firefox ในความเป็นจริงผลลัพธ์จะแตกต่างกันอย่างมากตามการใช้งาน JavaScript (ซึ่งก็ไม่ใช่เรื่องน่าประหลาดใจมากนัก) นี่คือหน้าทดสอบอย่างรวดเร็วและหยาบ (ด้านล่าง) สำหรับการใช้งานเบราว์เซอร์ (หยาบมาก ไม่ยอมให้พักระหว่างการทดสอบ ดังนั้นให้ข้อมูลตอบกลับน้อย และจะเจอข้อจำกัดเวลาในการรันสคริปต์) ผมแนะนำให้รีเฟรชหน้าระหว่างการทดสอบ; อย่างน้อยใน Firefox จะช้าลงหากทดสอบซ้ำโดยไม่รีเฟรช
เวอร์ชันที่ซับซ้อนพอสมควรซึ่งใช้ Array#concat นั้นเร็วกว่าการเริ่มต้นตรง ๆ บน FF เมื่อจำนวนอาเรย์อยู่ระหว่าง 1,000 ถึง 2,000 องค์ประกอบ แต่บนเอนจิน V8 ของ Chrome การเริ่มต้นตรง ๆ จะชนะทุกครั้ง...
นี่คือตัวทดสอบ:
const tests = [
{
name: "downpre",
total: 0,
desc: "Count down, pre-decrement",
func: makeWithCountDownPre
},
{
name: "downpost",
total: 0,
desc: "Count down, post-decrement",
func: makeWithCountDownPost
},
{
name: "up",
total: 0,
desc: "Count up (normal)",
func: makeWithCountUp
},
{
name: "downandup",
total: 0,
desc: "Count down (for loop) and up (for filling)",
func: makeWithCountDownArrayUp
},
{
name: "concat",
total: 0,
desc: "Concat",
func: makeWithConcat
}
];
const q = sel => document.querySelector(sel);
let markup = "";
for (const {name, desc} of tests) {
markup += `
<div><input type="checkbox" id="chk_${name}" checked>
<label for="chk_${name}">${desc}</label></div>`;
}
q("#checkboxes").innerHTML = markup;
q("#btnTest").addEventListener("click", btnTestClick);
function btnTestClick() {
// Clear log
q("#log").innerHTML = "Testing...";
// Show running
q("#btnTest").disabled = true;
// Run after a pause while the browser updates display
setTimeout(btnTestClickPart2, 0);
}
function btnTestClickPart2() {
try {
runTests();
} catch (e) {
log(`Exception: ${e.message}`);
}
// Re-enable the button
q("#btnTest").disabled = false;
}
function getNumField(name) {
const val = q("#" + name).value.trim();
const num = /^\d+$/.test(val) ? parseInt(val) : NaN;
if (isNaN(num) || num <= 0) {
throw new Error(`Invalid ${name} value ${JSON.stringify(val)}`);
}
return num;
}
function runTests() {
try {
// Clear log
q("#log").innerHTML = "";
const runCount = getNumField("loops");
const length = getNumField("length");
// Do it (we run runCount + 1 times, first time is a warm up)
for (let counter = 0; counter <= runCount; ++counter) {
for (const test of tests) {
if (q("#chk_" + test.name).checked) {
const start = Date.now();
const a = test.func(length);
const time = Date.now() - start;
if (counter == 0) {
// Don't count (warm up), but do check the algorithm works
const invalid = validateResult(a, length);
if (invalid) {
log(`<span class=error>FAILURE</span> with test ${test.name}: ${invalid}`);
return;
}
} else {
// Count this one
log(`#${counter}: ${test.desc}: ${time}ms`);
test.total += time;
}
}
}
}
for (const test of tests) {
if (q("#chk_" + test.name).checked) {
test.avg = test.total / runCount;
if (typeof lowest != "number" || lowest > test.avg) {
lowest = test.avg;
}
}
}
let results =
"<p>Results:" +
"<br>Length: " + length +
"<br>Loops: " + runCount +
"</p>";
for (const test of tests) {
if (q("#chk_" + test.name).checked) {
results +=
`<p ${lowest == test.avg ? " class=winner" : ""}>${test.desc}, average time: ${test.avg}ms</p>`;
}
}
results += "<hr>";
q("#log").insertAdjacentHTML("afterbegin", results);
} catch (e) {
log(e.message);
return;
}
}
function validateResult(a, length) {
if (a.length != length) {
return "Length is wrong";
}
for (let n = length - 1; n >= 0; --n) {
if (a[n] != 0) {
return "Index " + n + " is not zero";
}
}
return undefined;
}
function makeWithCountDownPre(len) {
const a = new Array(len);
while (--len >= 0) {
a[len] = 0;
}
return a;
}
function makeWithCountDownPost(len) {
const a = new Array(len);
while (len-- > 0) {
a[len] = 0;
}
return a;
}
function makeWithCountUp(len) {
const a = new Array(len);
for (let i = 0; i < len; ++i) {
a[i] = 0;
}
return a;
}
function makeWithCountDownArrayUp(len) {
const a = new Array(len);
let i = 0;
while (--len >= 0) {
a[i++] = 0;
}
return a;
}
function makeWithConcat(len) {
if (len == 0) {
return [];
}
let a = [0];
let currlen = 1;
while (currlen < len) {
const rem = len - currlen;
if (rem < currlen) {
a = a.concat(a.slice(0, rem));
} else {
a = a.concat(a);
}
currlen = a.length;
}
return a;
}
function log(msg) {
const p = document.createElement("p");
p.textContent = msg;
q("#log").appendChild(p);
}body {
font-family: sans-serif;
}
#log p {
margin: 0;
padding: 0;
}
.error {
color: red;
}
.winner {
color: green;
}<div>
<label for='txtLength'>Length:</label><input type='text' id='length' value='1000'>
<br><label for='txtLoops'>Loops:</label><input type='text' id='loops' value='100000'>
<div id='checkboxes'></div>
<br><input type='button' id='btnTest' value='Test'>
<hr>
<div id='log'></div>
</div>คำตอบ #7
ถ้าคุณใช้ ES6 คุณสามารถใช้ Array.from() แบบนี้ได้:
Array.from({ length: 3 }, () => 0);
//[0, 0, 0]
มีผลลัพธ์เหมือนกับ
Array.from({ length: 3 }).map(() => 0)
//[0, 0, 0]
เพราะ
Array.from({ length: 3 })
//[undefined, undefined, undefined]
คำตอบ #8
โดยค่าเริ่มต้น คลาส Uint8Array, Uint16Array และ Uint32Array จะเก็บค่าเป็นศูนย์ ดังนั้นคุณไม่จำเป็นต้องใช้เทคนิคการเติมที่ซับซ้อน แค่ทำดังนี้:
var ary = new Uint8Array(10);
ทุกองค์ประกอบของอาร์เรย์ ary จะเป็นศูนย์โดยค่าเริ่มต้น
คำตอบ #9
การใช้สัญลักษณ์วัตถุ
var x = [];
เติมศูนย์ไหม? แบบว่า...
var x = [0,0,0,0,0,0];
เต็มไปด้วย 'undefined'...
var x = new Array(7);
การเขียนสัญลักษณ์ obj พร้อมศูนย์
var x = [];
for (var i = 0; i < 10; i++) x[i] = 0;
เป็นข้อสังเกตเพิ่มเติม หากคุณแก้ไขโปรโตไทป์ของ Array ทั้งคู่
var x = new Array();
และ
var y = [];
จะมีการปรับเปลี่ยนต้นแบบเหล่านั้น
อย่างไรก็ตาม ผมคงไม่ต้องกังวลมากเกินไปเกี่ยวกับประสิทธิภาพหรือความเร็วของกระบวนการนี้ เพราะยังมีสิ่งอื่น ๆ อีกมากมายที่คุณน่าจะทำซึ่งสิ้นเปลืองและมีค่าใช้จ่ายมากกว่าการสร้างอาเรย์ความยาวใดก็ได้ที่มีค่าเป็นศูนย์
คำตอบ #10
function makeArrayOf(value, length) {
var arr = [], i = length;
while (i--) {
arr[i] = value;
}
return arr;
}
makeArrayOf(0, 5); // [0, 0, 0, 0, 0]
makeArrayOf('x', 3); // ['x', 'x', 'x']
โปรดทราบว่า while มักจะมีประสิทธิภาพมากกว่า for-in, forEach เป็นต้น
คำตอบ #11
ฉันได้ทดสอบทุกการผสมของการจองล่วงหน้า/ไม่จองล่วงหน้า การนับขึ้น/นับลง และลูป for/while ใน IE 6/7/8, Firefox 3.5, Chrome และ Opera แล้ว
ฟังก์ชันด้านล่างนี้มีความเร็วสม่ำเสมอที่สุดหรือใกล้เคียงที่สุดใน Firefox, Chrome และ IE8 และไม่ได้ช้ากว่าฟังก์ชันที่เร็วที่สุดใน Opera และ IE6 มากนัก นอกจากนี้ยังเป็นฟังก์ชันที่ง่ายที่สุดและชัดเจนที่สุดตามความเห็นของฉัน ฉันพบว่ามีบางเบราว์เซอร์ที่เวอร์ชันลูป while ทำงานเร็วกว่าเล็กน้อย ดังนั้นฉันจึงรวมมันไว้ด้วยเพื่อเป็นข้อมูลอ้างอิง
function newFilledArray(length, val) {
var array = [];
for (var i = 0; i < length; i++) {
array[i] = val;
}
return array;
}
หรือ
function newFilledArray(length, val) {
var array = [];
var i = 0;
while (i < length) {
array[i++] = val;
}
return array;
}
คำตอบ #12
const arr = Array.from({ length: 10 }).fill(0);
console.log(arr)คำตอบ #13
วิธีแก้ปัญหา ES6:
[...new Array(5)].map(x => 0); // [0, 0, 0, 0, 0]
คำตอบ #14
หากคุณจำเป็นต้องสร้างอาเรย์ที่เต็มด้วยศูนย์หลายอาเรย์ที่มีความยาวต่างกันในระหว่างการทำงานของโค้ด วิธีที่เร็วที่สุดที่ฉันพบในการทำเช่นนี้คือการสร้างอาเรย์ที่เต็มด้วยศูนย์ ครั้งเดียว โดยใช้หนึ่งในวิธีที่กล่าวถึงในหัวข้อนี้ ของความยาวที่คุณรู้ว่าจะไม่มีการเกิน และจากนั้นจึงตัดอาเรย์นั้นตามความจำเป็น
ตัวอย่างเช่น (ใช้ฟังก์ชันจากคำตอบที่เลือกด้านบนเพื่อเริ่มต้นอาร์เรย์) สร้างอาร์เรย์ที่เติมด้วยศูนย์มีความยาว maxLength เป็นตัวแปรที่มองเห็นได้สำหรับโค้ดที่ต้องการอาร์เรย์ที่เต็มด้วยศูนย์:
var zero = newFilledArray(maxLength, 0);
ตอนนี้ตัดอาร์เรย์นี้ทุกครั้งที่คุณต้องการอาร์เรย์ที่เติมด้วยศูนย์ความยาว requiredLength < maxLength:
zero.slice(0, requiredLength);
ฉันเคยสร้างอาเรย์ที่เติมด้วยศูนย์เป็นพัน ๆ ครั้งระหว่างการรันโค้ดของฉัน ซึ่งเร่งกระบวนการได้อย่างมาก
คำตอบ #15
function zeroFilledArray(size) {
return new Array(size + 1).join('0').split('');
}
คำตอบ #16
การใช้ lodash หรือ underscore
_.range(0, length - 1, 0);
หรือหากคุณมีอาเรย์อยู่แล้วและคุณต้องการอาเรย์ที่มีความยาวเท่ากัน
array.map(_.constant(0));
คำตอบ #17
ฉันไม่มีอะไรต่อต้าน:
Array.apply(null, Array(5)).map(Number.prototype.valueOf,0);
new Array(5+1).join('0').split('').map(parseFloat);
แนะนำโดย Zertosh แต่ในส่วนขยายอาร์เรย์ ES6 ใหม่ คุณสามารถทำสิ่งนี้ได้โดยตรงด้วยเมธอด fill ตอนนี้ IE Edge, Chrome และ FF รองรับแล้ว แต่ตรวจสอบตารางความเข้ากันได้
`new Array(3).fill(0)` จะให้คุณ `[0, 0, 0]` คุณสามารถเติมค่าลงในอาเรย์ด้วยค่าต่าง ๆ ได้เช่น `new Array(5).fill('abc')` (สามารถใช้วัตถุและอาเรย์อื่น ๆ ได้ด้วย)
นอกจากนี้คุณยังสามารถแก้อาร์เรย์ก่อนหน้าด้วย fill:
arr = [1, 2, 3, 4, 5, 6]
arr.fill(9, 3, 5) # what to fill, start, end
ซึ่งจะให้คุณได้: [1, 2, 3, 9, 9, 6]
คำตอบ #18
เพื่อสร้างอาร์เรย์ใหม่ทั้งหมด
new Array(arrayLength).fill(0);
เพื่อเพิ่มค่าบางค่าไปที่ส่วนท้ายของอาร์เรย์ที่มีอยู่
[...existingArray, ...new Array(numberOfElementsToAdd).fill(0)]ตัวอย่าง
//**To create an all new Array**
console.log(new Array(5).fill(0));
//**To add some values at the end of an existing Array**
let existingArray = [1,2,3]
console.log([...existingArray, ...new Array(5).fill(0)]);คำตอบ #19
วิธีที่ฉันมักทำ (และเร็วมาก) คือการใช้ Uint8Array ตัวอย่างเช่น การสร้างเวกเตอร์ที่เติมด้วยศูนย์จำนวน 1 ล้านองค์ประกอบ:
var zeroFilled = [].slice.apply(new Uint8Array(1000000))
ฉันเป็นผู้ใช้ Linux และมันก็ใช้ได้เสมอสำหรับฉัน แต่ครั้งหนึ่งเพื่อนที่ใช้ Mac มีบางองค์ประกอบที่ไม่เป็นศูนย์ ฉันคิดว่าเครื่องของเขามีปัญหา แต่ถึงอย่างนั้น นี่คือวิธีที่ปลอดภัยที่สุดที่เราพบเพื่อแก้ไข:
var zeroFilled = [].slice.apply(new Uint8Array(new Array(1000000))
แก้ไขแล้ว
โครม 25.0.1364.160
- เฟรเดอริก กอตลีบ - 6.43
- แซม บาร์นัม - 4.83
- อีไล - 3.68
- โยชูวา 2.91
- แมทธิว ครัมลีย์ - 2.67
- bduran - 2.55
- อัลเลน ไรซ์ - 2.11
- kangax - 0.68
- ทีเจ คราวเดอร์ - 0.67
- zertosh - ข้อผิดพลาด
ไฟร์ฟอกซ์ 20.0
- อัลเลน ไรซ์ - 1.85
- ยอชูวา - 1.82
- แมทธิว ครัมลีย์ - 1.79
- bduran - 1.37
- เฟรเดอริก กอตลีบ - 0.67
- แซม บาร์นัม - 0.63
- อีไล - 0.59
- kagax - 0.13
- ทีเจ คราวเดอร์ - 0.13
- zertosh - ข้อผิดพลาด
พลาดการทดสอบที่สำคัญที่สุด (อย่างน้อยก็สำหรับฉัน): การทดสอบ Node.js ฉันสงสัยว่ามันใกล้กับมาตรฐานของ Chrome

