शून्य भरा जावास्क्रिप्ट सरणी बनाने के लिए सबसे कुशल तरीका?


602

जावास्क्रिप्ट में एक मनमाना लंबाई शून्य भरा सरणी बनाने का सबसे कुशल तरीका क्या है?


7
इस पर कुछ वास्तविक डेटा: jsperf.com/zeroarrayjs
Web_Designer

7
ईएस 6 भरण यह मूल रूप से करने की अनुमति देता है।
साल्वाडोर डाली

1
arr = new Array (लंबाई + 1) .joint (वर्ण) .split ('');
जॉर्डन स्टेफानेली 19

4
UPDATE 2016 : एक और कस्टम बेंचमार्क यहां: jsfiddle.net/basickarl/md5z0Lqq
कार्ल मॉरिसन

1
let i = 0; Array.from(Array(10), ()=>i++);
बार्ट होकेस्ट्रा

जवाबों:


543

ईएस 6 पेश करता है Array.prototype.fill। इसका उपयोग इस तरह किया जा सकता है:

new Array(len).fill(0);

यकीन नहीं है कि यह तेज़ है, लेकिन मुझे यह पसंद है क्योंकि यह छोटा और आत्म-वर्णन है।

यह अभी भी IE ( संगतता की जांच ) में नहीं है, लेकिन एक पॉलीफ़िल उपलब्ध है


15
भरण तेज है। new Array(len)दर्द धीमा है। (arr = []).length = len; arr.fill(0);सबसे तेज घोल के बारे में कहीं भी देखा जाता है ... या कम से कम बंधा हुआ
पिंप ट्राइज़किट

7
@PimpTrizkit arr = Array(n)और (arr = []).length = nयुक्ति के अनुसार पहचान का व्यवहार करें। कुछ कार्यान्वयन में एक तेज़ हो सकता है, लेकिन मुझे नहीं लगता कि कोई बड़ा अंतर है।
ओरिऑल

2
खैर, मैंने इसे बहुआयामी सरणियों के साथ परीक्षण करना शुरू कर दिया और यह मेरे परीक्षण मामलों को बहुत तेज करने लगा। अभी FF41 और Chrome45.0.2454.99 मीटर पर कुछ और परीक्षण किए हैं। हां, मुझे लगता है कि मुझे खुद को समझाने के लिए वास्तव में अधिक स्थान की आवश्यकता थी। मेरा अधिकांश परीक्षण पूर्वाग्रह था जिसे मैं स्वीकार करूंगा। लेकिन, इसे देखें। एक var को पूर्वनिर्धारित करें और गति के (arr = []).length = 1000; खिलाफ इस लाइन का उपयोग करके arr = new Array(1000);इसे Chrome और FF दोनों में टेस्ट करें ... newबहुत धीमा है। अब, सरणी की लंबाई छोटी है .. कहते हैं <50 या वहाँ के बारे में ... तो new Array()बेहतर प्रदर्शन करने लगता है। लेकिन ..
पिंप ट्राइज़किट

4
... मैं मानता हूँ कि मैं इस भाग से चूक गया ... जब मैं परीक्षण में दूसरी पंक्ति जोड़ता हूँ ... arr.fill(0) ... सब कुछ बदल जाता है। अब, new Array()ज्यादातर मामलों में उपयोग तेज है , जब आप सरणी आकार> 100000 ... को छोड़कर, तब आप फिर से गति में वृद्धि देखना शुरू कर सकते हैं। लेकिन अगर आपको वास्तव में शून्य के साथ इसे पूर्वनिर्मित नहीं करना है और खाली सरणियों के मानक फालिज का उपयोग कर सकते हैं। फिर (arr = []).length = xज्यादातर समय मेरे टेस्ट के मामलों में पागल रहता है।
पिंप ट्राइजकिट

4
ध्यान दें कि सरणी (जैसे नक्शा या forEach) पर पुनरावृति करने के लिए मानों को सेट किया जाना चाहिए , अन्यथा यह उन अनुक्रमितों को छोड़ देगा। आपके द्वारा निर्धारित मूल्य जो भी आप चाहते हैं - अपरिभाषित हो सकते हैं। उदाहरण: कोशिश new Array(5).forEach(val => console.log('hi'));बनाम new Array(5).fill(undefined).forEach(val => console.log('hi'));
अरनहुगो

387

हालांकि यह एक पुराना धागा है, मैं इसमें अपने 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]

6
बहुत बढ़िया जवाब! क्या आप कृपया इसके साथ चाल बता सकते हैं Array.apply(null, new Array(5)).map(...)? कारण बस कर (नया ऐरे (5))। नक्शा (...) युक्ति के रूप में काम नहीं करेगा बताता है
दिमित्री पश्केविच

36
(btw, हमें वास्तव में ज़रूरत नहीं है new) जब आप ऐसा Array(5)करते हैं तो आप एक ऐसी वस्तु बना रहे हैं जो थोड़े इस तरह दिखती है: { length: 5, __proto__: Array.prototype }- कोशिश करें console.dir( Array(5) )। सूचना है कि यह किसी भी गुण नहीं हैं 0, 1, 2, आदि लेकिन जब आप applyकि पर्यत Arrayनिर्माता है, यह कह रही है की तरह है Array(undefined, undefined, undefined, undefined, undefined)। और आपको एक ऑब्जेक्ट मिलता है जो थोड़े जैसा दिखता है { length: 5, 0: undefined, 1: undefined...}mapगुण पर काम करता है 0, 1आदि है और इसीलिए आपके उदाहरण काम नहीं करता है, लेकिन आप का उपयोग जब applyयह होता है।
15 सितंबर को जर्टोश

4
के लिए पहला पैरामीटर .applyवास्तव में वही है जो आप चाहते thisहैं। इन उद्देश्यों के लिए thisकोई फर्क नहीं पड़ता है - हम केवल "सुविधा" के फैलने वाले पैरामीटर के बारे में परवाह करते हैं .apply- इसलिए इसका कोई भी मूल्य हो सकता है। मुझे पसंद है nullक्योंकि यह सस्ता है, आप शायद इसका उपयोग नहीं करना चाहते हैं {}या []तब से जब तक आप बिना किसी कारण के किसी वस्तु को तत्काल भेज देंगे।
ज़र्टोश

2
इसके अलावा आकार + असाइन के साथ आरंभ करना पुश की तुलना में बहुत तेज है। टेस्ट केस देखें jsperf.com/zero-fill-2d-array
कॉलिन

2
Array.apply (null, Array (5)) के बारे में क्या है? मानचित्र (x => 0)? यह थोड़ा छोटा है!
आर्क लिनक्स टक्स

97

पूर्वनिर्मित मूल्यों के साथ एक सरणी भरने के लिए सुरुचिपूर्ण तरीका

यहाँ 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());
}

इस पद्धति का उपयोग कॉलबैक में दिए गए सूचकांक पैरामीटर का लाभ उठाकर संख्याओं के अनुक्रम उत्पन्न करने के लिए भी किया जा सकता है:

> Array.from(Array(10), (d, i) => i)
< [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

बोनस उत्तर: स्ट्रिंग का उपयोग करके एक सरणी भरें repeat()

चूँकि इस जवाब को अच्छी तरह से ध्यान दिया जा रहा है, मैं भी इस शांत चाल को दिखाना चाहता था। यद्यपि मेरे मुख्य उत्तर के रूप में उपयोगी नहीं है, फिर भी बहुत ज्ञात नहीं, लेकिन बहुत उपयोगी स्ट्रिंग repeat()पद्धति का परिचय देगा । यहाँ चाल है:

> "?".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]

उस पोस्ट में बहुत सारे पार्लर के ट्रिक्स, लेकिन उम्मीद है कि कोई भी प्रोडक्शन कोड तक नहीं पहुंचेगा :)
एरिक ग्रेंज

हालांकि repeatचाल निश्चित रूप से उत्पादन में नहीं चाहता है, Array.from()पूरी तरह से ठीक है :-)
लुसियो पावा

वास्तव में नहीं, Array.from () यहाँ मूल रूप से एक सरणी बना रहा है, नक्शे के साथ इसके माध्यम से पुनरावृत्ति करता है (), प्रत्येक आइटम पर एक नया सरणी बनाने के लिए एक फ़ंक्शन को कॉल करता है, फिर पहला सरणी त्यागता है ... एक छोटे सरणियों के लिए यह हो सकता है सहज ज्ञान युक्त, बड़े सरणियों के लिए, यह उस तरह का पैटर्न है जिसके परिणामस्वरूप लोग ब्राउज़र को "मेमोरी हॉग" कहते हैं :)
एरिक ग्रेंज

बड़े सरणियों से निपटने वाले लोगों को इससे बेहतर पता होना चाहिए, निश्चित रूप से। सामान्य ऐप्स के लिए, हालांकि, एक नियमित आकार के ऐक्स सरणी (10k तत्वों तक) का निर्माण किया जाएगा, जो तुरंत निपट जाएगा, बिल्कुल ठीक है (यदि आप अतिरिक्त सरणी निर्माण से बचते हैं - तो नवीनतम क्रोम के साथ परीक्षण किया गया)। उस तरह के मामलों के लिए, पठनीयता छोटे प्रदर्शन अनुकूलन से अधिक महत्वपूर्ण हो जाती है। O (n) समय के बारे में, यह आवश्यक है यदि आपको प्रत्येक तत्व (मेरे उत्तर का मुख्य विषय) के लिए कुछ अलग करने की आवश्यकता है। यह चर्चा बहुत दिलचस्प है, खुशी है कि आपने इसे उठाया!
लुसियो पाइवा

88

कम से कम

Array(n).fill(0)

(16 चार), जहां nसरणी का आकार है


2018.10.28 मैंने अन्य उत्तरों से 15 प्रस्तावों की तुलना की। मैक ओएस एक्स 10.13.6 हाई सिएरा पर तीन ब्राउज़रों पर परीक्षण किया गया: क्रोम 69.0.3497, सफारी 12.0 (13606.2.11) और फ़ायरफ़ॉक्स 63.0 (64 बिट)।

N = 100000 के लिए परिणाम

नीचे मैं सबसे तेज़ ब्राउज़र (सफारी) के लिए परिणाम दिखाता हूँ:

यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें

सभी ब्राउज़रों के लिए सबसे तेज़ समाधान एम था - हालांकि यह "विशिष्ट सरणी" नहीं है (लेकिन बहुत तेज़ है) - सफारी 33.8k संचालन / दूसरा, क्रोम 5.2k, FF 3.5k,

विशिष्ट सरणियों के लिए सबसे तेज़ समाधान:

  • और बीसफारी 5.5k और क्रोम 1.1k के लिए (समान था) (फ़ायरफ़ॉक्स 0.1k, बी 0.06k पर)
  • फ़ायरफ़ॉक्स 0.6k (सफारी 3.1k, क्रोम 1.1k पर) के लिए एफ
  • क्रोम और सफारी के लिए A, B, F परिणामों के करीब था

सबसे धीमा समाधान:

  • जी सफारी 0.02k और फ़ायरफ़ॉक्स 0.04k (क्रोम 0.1k पर)
  • D क्रोम 0.04k पर (सफारी 0.33k पर, फ़ायरफ़ॉक्स 0.15k पर)

समाधान एन केवल फ़ायरफ़ॉक्स और क्रोम पर काम करता है।

N = 10 के लिए परिणाम

सबसे तेजी से:

  • Chrome 17.3M और Safari 13.3M (Firefox 4.7M) पर सबसे तेज़ था
  • A, B फ़ायरफ़ॉक्स 16.9M (Chrome 15.6M, Safari 3.5M) पर समान और सबसे तेज़ था

सबसे धीमा:

  • हे लिए सफारी 0.35M
  • , क्रोम 0.35M के लिए
  • फ़ायरफ़ॉक्स 0.31M के लिए एन

निष्कर्ष

  • सभी ब्राउज़रों पर सबसे तेज़ समाधान ( nफ़ायरफ़ॉक्स पर छोटा छोड़कर ) एम था let a = new Float32Array(n)(हालांकि विशिष्ट सरणी नहीं है) - इसके लिए सबसे तेज़ ब्राउज़र सफारी था (बड़े के लिए)n > क्रोम की तुलना में 6 गुना तेज,> फ़ायरफ़ॉक्स की तुलना में 9 गुना तेज़)
  • विशिष्ट सरणियों के लिए पसंदीदा समाधान let a = Array(n).fill(0) (तेज और लघु कोड) है

आप यहां अपनी मशीन पर परीक्षण कर सकते हैं ।


बस Chrome 77 पर कुछ परीक्षण चलाए और पुश के साथ एक साधारण लूप () भरने की तुलना में दोगुना तेज है () ... मुझे आश्चर्य है कि भराव के सूक्ष्म दुष्प्रभाव () क्या अधिक कुशल कार्यान्वयन को रोकते हैं?
एरिक ग्रेंज

@EricGrange मैं अपडेट का जवाब देता हूं - नीचे मैं आपके प्रस्ताव के साथ benchamrk के लिंक को अपडेट करता हूं: केस P let a=[]; for(i=n;i--;) a.push(0);- लेकिन यह 4x से धीमा है fill(0)- इसलिए मैं उस मामले में चित्र चुड़ैल को भी अपडेट नहीं करूंगा।
Kamil Kiełczewski

2
अच्छा माप। विश्लेषण: हर पुनरावृत्ति पर सरणी का आकार बदलने के कारण जी धीमा है, और आकार बदलने का अर्थ है एक नया मेमोरी आवंटन करना। ए, बी, एम फास्ट क्योंकि साइजिंग केवल एक बार किया जाता है। +1
रोलैंड

यह उन कुछ उत्तरों में से एक है जो वास्तव में पूछे गए प्रश्न का उत्तर देने का प्रयास करता है। अनजाने में यह एक गैर-उत्तर में चिपक कर विफल हो जाता है और सबसे तेज वास्तविक उत्तर को याद नहीं करता है, कम से कम जून 2020 में सभी ब्राउज़रों में जो है a = new Array(n); for (let i = 0; i < n; ++i) a[i] = 0;टेस्ट
gman

63

पहले से ही वर्णित ईएस 6 भरण विधि इस बात का ध्यान रखता है। अधिकांश आधुनिक डेस्कटॉप ब्राउज़र पहले से ही आज (क्रोमियम, एफएफ, एज और सफारी) [ 1 ] के रूप में आवश्यक ऐरे प्रोटोटाइप तरीकों का समर्थन करते हैं । आप MDN पर विवरण देख सकते हैं । एक सरल उपयोग उदाहरण है

a = new Array(10).fill(0);

वर्तमान ब्राउज़र समर्थन को देखते हुए आपको इसका उपयोग करने के लिए सतर्क रहना चाहिए जब तक कि आप सुनिश्चित न हों कि आपके दर्शक आधुनिक डेस्कटॉप ब्राउज़र का उपयोग करते हैं।


4
यदि आप एक संदर्भ प्रकार से भरते हैं तो यह उन सभी में समान संदर्भ होगा। new Array (10) .fill (null) .map (() => []]
इसको

4
UPDATE 2016 : यह विधि पानी से बाहर की हर चीज को उड़ा देती है, बेंचमार्क के लिए यहां क्लिक करें: jsfiddle.net/basickarl/md5z0Lqq
Karl Morrison

यह सरणियों के लिए काम करेगा। a = Array(10).fill(null).map(() => { return []; });
एंडी

2
@AndrewAnthonyGerst Terser:a = Array(10).fill(0).map( _ => [] );
फ़्रोगज़

50

नोट अगस्त 2013 को जोड़ा गया, फरवरी 2015 को अपडेट किया गया: 2009 से नीचे का उत्तर जावास्क्रिप्ट के सामान्य Arrayप्रकार से संबंधित है । यह ES2015 में परिभाषित नए टाइप किए गए सरणियों से संबंधित नहीं है [और अब कई ब्राउज़रों में उपलब्ध है], जैसे Int32Arrayऔर ऐसे। यह भी ध्यान दें कि ES2015 Arrays और टाइप किए गए सरणियोंfill दोनों के लिए एक विधि जोड़ता है , जो आपको भरने के लिए सबसे कुशल तरीका होने की संभावना है ...

इसके अलावा, यह कुछ कार्यान्वयन के लिए एक बड़ा अंतर बना सकता है कि आप सरणी कैसे बनाते हैं। क्रोम का V8 इंजन, विशेष रूप से, अत्यधिक कुशल, अस्पष्ट-मेमोरी सरणी का उपयोग करने की कोशिश करता है, अगर यह सोचता है कि यह आवश्यक होने पर ही ऑब्जेक्ट-आधारित सरणी में स्थानांतरित हो सकता है।


अधिकांश भाषाओं के साथ, यह पूर्व-आबंटित होगा, फिर इस तरह शून्य-भरण:

function newFilledArray(len, val) {
    var rv = new Array(len);
    while (--len >= 0) {
        rv[len] = val;
    }
    return rv;
}

लेकिन , जावास्क्रिप्ट सरणियाँ वास्तव में सरणियाँ नहीं हैं , वे अन्य सभी जावास्क्रिप्ट वस्तुओं की तरह ही कुंजी / मान मानचित्र हैं, इसलिए ऐसा करने के लिए कोई "पूर्व-आबंटित" नहीं है (लंबाई सेट करने के लिए आवंटित नहीं है कि भरने के लिए कई स्लॉट), न ही क्या यह मानने का कोई कारण है कि शून्य से नीचे की गणना करने का लाभ (जो कि लूप में तुलना करने के लिए बस तेज है) को रिवर्स ऑर्डर में कुंजियों को जोड़कर आगे नहीं बढ़ाया जाता है जब कार्यान्वयन अच्छी तरह से कुंजी की हैंडलिंग को अनुकूलित कर सकता है। सिद्धांत पर सरणियों से संबंधित आप आमतौर पर उन्हें क्रम में करेंगे।

वास्तव में, मैथ्यू क्रुमली ने बताया कि नीचे की गिनती की तुलना में फ़ायरफ़ॉक्स पर गिनती धीमी है, जिसके परिणामस्वरूप मैं पुष्टि कर सकता हूं - यह इसका सरणी भाग है (शून्य तक लूपिंग अभी भी एक संस्करण में एक सीमा तक लूपिंग की तुलना में तेज़ है)। जाहिरा तौर पर तत्वों को रिवर्स ऑर्डर में सरणी में जोड़ना फ़ायरफ़ॉक्स पर धीमी गति से ऑप है। वास्तव में, जावास्क्रिप्ट कार्यान्वयन द्वारा परिणाम काफी भिन्न होते हैं (जो कि आश्चर्य की बात नहीं है)। ब्राउज़र कार्यान्वयन के लिए एक त्वरित और गंदा परीक्षण पृष्ठ (नीचे), बहुत गंदा है, परीक्षणों के दौरान उपज नहीं देता है, इसलिए न्यूनतम प्रतिक्रिया प्रदान करता है और स्क्रिप्ट समय सीमा से दूर चलेगा)। मैं परीक्षणों के बीच ताज़ा करने की सलाह देता हूं; यदि आप नहीं करते हैं तो एफएफ (कम से कम) दोहराया परीक्षणों पर धीमा हो जाता है।

काफी जटिल संस्करण जो Array # concat का उपयोग करता है, FF पर सीधे init से 1,000 और 2,000 तत्व सरणियों के बीच कहीं अधिक तेज़ है। क्रोम के V8 इंजन पर, हालांकि, हर बार सीधा इनिट बाहर जीत जाता है ...

यहाँ परीक्षण पृष्ठ ( लाइव कॉपी ) है:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Zero Init Test Page</title>
<style type='text/css'>
body {
    font-family:    sans-serif;
}
#log p {
    margin:     0;
    padding:    0;
}
.error {
    color:      red;
}
.winner {
    color:      green;
    font-weight:    bold;
}
</style>
<script type='text/javascript' src='prototype-1.6.0.3.js'></script>
<script type='text/javascript'>
var testdefs = {
    'downpre':  {
        total:  0,
        desc:   "Count down, pre-decrement",
        func:   makeWithCountDownPre
    },
    'downpost': {
        total:  0,
        desc:   "Count down, post-decrement",
        func:   makeWithCountDownPost
    },
    'up':       {
        total:  0,
        desc:   "Count up (normal)",
        func:   makeWithCountUp
    },
    'downandup':  {
        total:  0,
        desc:   "Count down (for loop) and up (for filling)",
        func:   makeWithCountDownArrayUp
    },
    'concat':   {
        total:  0,
        desc:   "Concat",
        func:   makeWithConcat
    }
};

document.observe('dom:loaded', function() {
    var markup, defname;

    markup = "";
    for (defname in testdefs) {
        markup +=
            "<div><input type='checkbox' id='chk_" + defname + "' checked>" +
            "<label for='chk_" + defname + "'>" + testdefs[defname].desc + "</label></div>";
    }
    $('checkboxes').update(markup);
    $('btnTest').observe('click', btnTestClick);
});

function epoch() {
    return (new Date()).getTime();
}

function btnTestClick() {

    // Clear log
    $('log').update('Testing...');

    // Show running
    $('btnTest').disabled = true;

    // Run after a pause while the browser updates display
    btnTestClickPart2.defer();
}
function btnTestClickPart2() {

    try {
        runTests();
    }
    catch (e) {
        log("Exception: " + e);
    }

    // Re-enable the button; we don't yheidl
    $('btnTest').disabled = false;
}

function runTests() {
    var start, time, counter, length, defname, def, results, a, invalid, lowest, s;

    // Get loops and length
    s = $F('txtLoops');
    runcount = parseInt(s);
    if (isNaN(runcount) || runcount <= 0) {
        log("Invalid loops value '" + s + "'");
        return;
    }
    s = $F('txtLength');
    length = parseInt(s);
    if (isNaN(length) || length <= 0) {
        log("Invalid length value '" + s + "'");
        return;
    }

    // Clear log
    $('log').update('');

    // Do it
    for (counter = 0; counter <= runcount; ++counter) {

        for (defname in testdefs) {
            def = testdefs[defname];
            if ($('chk_' + defname).checked) {
                start = epoch();
                a = def.func(length);
                time = epoch() - start;
                if (counter == 0) {
                    // Don't count (warm up), but do check the algorithm works
                    invalid = validateResult(a, length);
                    if (invalid) {
                        log("<span class='error'>FAILURE</span> with def " + defname + ": " + invalid);
                        return;
                    }
                }
                else {
                    // Count this one
                    log("#" + counter + ": " + def.desc + ": " + time + "ms");
                    def.total += time;
                }
            }
        }
    }

    for (defname in testdefs) {
        def = testdefs[defname];
        if ($('chk_' + defname).checked) {
            def.avg = def.total / runcount;
            if (typeof lowest != 'number' || lowest > def.avg) {
                lowest = def.avg;
            }
        }
    }

    results =
        "<p>Results:" +
        "<br>Length: " + length +
        "<br>Loops: " + runcount +
        "</p>";
    for (defname in testdefs) {
        def = testdefs[defname];
        if ($('chk_' + defname).checked) {
            results += "<p" + (lowest == def.avg ? " class='winner'" : "") + ">" + def.desc + ", average time: " + def.avg + "ms</p>";
        }
    }
    results += "<hr>";
    $('log').insert({top: results});
}

function validateResult(a, length) {
    var n;

    if (a.length != length) {
        return "Length is wrong";
    }
    for (n = length - 1; n >= 0; --n) {
        if (a[n] != 0) {
            return "Index " + n + " is not zero";
        }
    }
    return undefined;
}

function makeWithCountDownPre(len) {
    var a;

    a = new Array(len);
    while (--len >= 0) {
        a[len] = 0;
    }
    return a;
}

function makeWithCountDownPost(len) {
    var a;

    a = new Array(len);
    while (len-- > 0) {
        a[len] = 0;
    }
    return a;
}

function makeWithCountUp(len) {
    var a, i;

    a = new Array(len);
    for (i = 0; i < len; ++i) {
        a[i] = 0;
    }
    return a;
}

function makeWithCountDownArrayUp(len) {
    var a, i;

    a = new Array(len);
    i = 0;
    while (--len >= 0) {
        a[i++] = 0;
    }
    return a;
}

function makeWithConcat(len) {
    var a, rem, currlen;

    if (len == 0) {
        return [];
    }
    a = [0];
    currlen = 1;
    while (currlen < len) {
        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) {
    $('log').appendChild(new Element('p').update(msg));
}
</script>
</head>
<body><div>
<label for='txtLength'>Length:</label><input type='text' id='txtLength' value='10000'>
<br><label for='txtLoops'>Loops:</label><input type='text' id='txtLoops' value='10'>
<div id='checkboxes'></div>
<br><input type='button' id='btnTest' value='Test'>
<hr>
<div id='log'></div>
</div></body>
</html>

यकीन नहीं है कि बैकवर्ड फिलिंग यहां मायने रखती है, बशर्ते आप केवल एक्सेसिंग एलिमेंट्स (उन्हें डिलीट न कर रहे हों) और आपको पहले से ही आवंटित किया गया हो। क्या मै गलत हु?
त्रिफलक

बैकवर्ड फिल का बिंदु विशेष रूप से सरणी के साथ नहीं है, यह थोड़ी देर के लिए भागने की स्थिति के साथ करना है - फाल्सी 0 लूप को बहुत कुशलता से समाप्त करता है
20

(हालांकि मैंने अभी देखा है कि यह कोड वास्तव में उस का उपयोग नहीं करता है)
annakata

@annakata, आप यहां इसका उपयोग नहीं कर सकते, क्योंकि 0 एक वैध सूचकांक है।
ट्राइप्टिक

@triptych: सच नहीं है, यह सब सही क्रम है - मेरी पोस्ट देखें
annakata

34

डिफ़ॉल्ट रूप से Uint8Array, Uint16Arrayऔर Uint32Arrayकक्षाएं शून्य को अपने मान के रूप में रखती हैं, इसलिए आपको किसी भी जटिल भरने की तकनीक की आवश्यकता नहीं है, बस करें:

var ary = new Uint8Array(10);

सरणी के सभी तत्व aryडिफ़ॉल्ट रूप से शून्य होंगे।


5
यह अच्छा है, लेकिन ध्यान दें कि इसे सामान्य सरणी के समान नहीं माना जा सकता है, उदाहरण के Array.isArray(ary)लिए false। लंबाई भी केवल पढ़ने के लिए है ताकि आप इसके साथ नई वस्तुओं को आगे न बढ़ा ary.push
सकें

Fwiw सभी टाइप किए गए सरणियों 0को उनके डिफ़ॉल्ट मान के रूप में रखें ।
jfunk

2
@MusikAnimal, Array.from(new Uint8Array(10))एक सामान्य सरणी प्रदान करेगा।
टॉमस लैंगकास

@TomasLangkaas: हाँ, लेकिन एक और जवाब से पता चलता है कि Array(n).fill(0)क्रोम की तुलना में लगभग 5 गुना धीमा है अगर आपको वास्तव में एक जेएस एरे की जरूरत है। यदि आप एक TypedArray का उपयोग कर सकते हैं, तो यह तुलना में बहुत तेज़ है .fill(0), हालाँकि, विशेष रूप से यदि आप के डिफ़ॉल्ट आरंभीकरण मूल्य का उपयोग कर सकते हैं 0। ऐसा लगता नहीं है कि एक निर्माता को भरने-मूल्य और लंबाई लगती है, जिस तरह से सी ++ के std::vectorपास है। यह किसी भी गैर-शून्य मान के लिए लगता है कि आपको एक शून्य टाइप्डएरे का निर्माण करना है और फिर उसे भरना है। : /
पीटर कॉर्ड्स

29

यदि आप 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]

23
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आदि


3
क्या iस्थानीय चर विलुप्त नहीं है? lengthमूल्य से पारित कर दिया है ताकि आप इसे सीधे गिरावट में सक्षम होना चाहिए।
शॉन ब्राइट

3
हालांकि यह पहली बार में बहुत अच्छा लग रहा है, दुर्भाग्य से यह एक अरमानी (जैसे arr[i] = value) में एक मनमाना बिंदु पर मूल्यों को असाइन करने के लिए बहुत धीमा है । यह शुरू से अंत तक और उपयोग करने के लिए लूप के लिए बहुत तेज़ है arr.push(value)। यह कष्टप्रद है, क्योंकि मुझे आपकी विधि पसंद है।
निक ब्रंट

19

ऑब्जेक्ट नोटेशन का उपयोग करना

var x = [];

शून्य भरा? पसंद...

var x = [0,0,0,0,0,0];

'अपरिभाषित' से भरा ...

var x = new Array(7);

शून्य के साथ obj संकेतन

var x = [];
for (var i = 0; i < 10; i++) x[i] = 0;

एक साइड नोट के रूप में, यदि आप ऐरे के प्रोटोटाइप को संशोधित करते हैं, तो दोनों

var x = new Array();

तथा

var y = [];

उन प्रोटोटाइप संशोधनों होगा

किसी भी दर पर, मैं इस ऑपरेशन की दक्षता या गति के बारे में अधिक चिंतित नहीं होगा, बहुत सारी अन्य चीजें हैं जो आप संभवतः कर रहे हैं जो शून्य से अधिक की मनमानी लंबाई की एक सरणी को स्थापित करने की तुलना में कहीं अधिक बेकार और महंगी हैं।


5
Err ... nullइस सरणी में कोई s नहीं हैं -var x = new Array(7);
kangax

5
वास्तव में, सरणी नए ऐरे (n) के साथ कुछ भी नहीं भरती है, अपरिभाषित भी नहीं है, यह बस सरणियों की लंबाई मान को n पर सेट करता है। आप इसे (नया ऐरे (1)) कॉल करके जांच सकते हैं। forEach (...) forEach कभी भी क्रियान्वित नहीं होता है, अगर आप इसे [अपरिभाषित] कहें तो इसके विपरीत।
जूसीआर

4
new Array(7)करता नहीं एक सरणी "अपरिभाषित से भरा" पैदा करते हैं। यह लंबाई के साथ एक खाली सरणी बनाता है 7.
23

1
आप अपने उत्तर के कुछ हिस्सों पर पुनर्विचार करना चाह सकते हैं क्योंकि @RobG जो कह रहा है वह महत्वपूर्ण है (यदि आप जो कह रहे हैं वह सच है, मैपिंग करना बहुत आसान होगा)
Abdo

1
इन दिनों आप कर सकते थे (new Array(10)).fill(0)
जेवियर डे ला रोजा

18

मैंने पूर्व-आवंटन / पूर्व-आवंटन के सभी संयोजनों का परीक्षण किया है, IE 6/7/8, फ़ायरफ़ॉक्स 3.5, क्रोम, और ओपेरा में छोरों के लिए / नीचे की गिनती करते हुए / के लिए / पूर्व-आवंटन नहीं किया है।

नीचे दिए गए फ़ंक्शंस फ़ायरफ़ॉक्स, क्रोम, और IE8 में लगातार सबसे तेज़ या बेहद नज़दीकी थे, और ओपेरा और आईई 6 में सबसे तेज़ से ज्यादा धीमा नहीं था। यह मेरी राय में सबसे सरल और स्पष्ट भी है। मुझे कई ब्राउज़र मिले हैं जहाँ लूप संस्करण थोड़ा तेज़ है, इसलिए मैं इसे संदर्भ के लिए भी शामिल कर रहा हूँ।

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;
}

1
आप var array = []घोषणा को वास्तव में लूप के पहले भाग में फेंक सकते हैं , केवल एक अल्पविराम द्वारा अलग किया गया है।
डेमियनब

मुझे डेमियनब का यह सुझाव पसंद है, लेकिन याद रखें कि वृद्धि से पहले असाइनमेंट और अल्पविराम लगाएं! `के लिए (var i = 0; मैं <लंबाई; सरणी [i] = वैल, i ++);
दंडित

वह करें जो हर कोई आपके दूसरे के लिए याद कर रहा है, और lengthपहले से दिए गए मान के लिए सरणी की लंबाई निर्धारित करें ताकि यह लगातार बदल न जाए। मेरी मशीन पर शून्य से 40 मिलियन से 8 तक की 1 मिलियन लंबाई की सरणी लाया।
जोनाथन ग्रे

मुझे लगता है जब मैं एक लाइनर में इस समाधान refactor 10-15% गति वृद्धि हो रही है। for (i = 0, array = []; i < length; ++i) array[i] = val;.. बहुत कम ब्लॉक? ... किसी भी तरह, ... अगर मैं array.lengthलंबाई के लिए नई सरणी सेट करता हूं .. तो मुझे लगता है कि एफएफ में एक और 10% -15% की गति वृद्धि हुई है ... क्रोम में, यह गति को दोगुना करने के लिए लगता है -> var i, array = []; array.length = length; while(i < length) array[i++] = val;(अभी भी तेज था अगर मैंने इसे एक forलूप के रूप में छोड़ दिया ... लेकिन while
इनिट की

मैं यह भी नोट करूंगा कि मेरे परीक्षण में। मेरे परीक्षण के मामलों की एक सभ्य संख्या में, ऊपर का अंतिम संस्करण 10x से अधिक तेजी से 3x से अच्छा प्रदर्शन करता है ... मुझे इतना यकीन नहीं है कि क्यों ... (क्रोम और एफएफ के बीच अलग-अलग सरणी आकार का परीक्षण किया गया है)
पिंप ट्राइज़किट

13

यदि आपको अपने कोड के निष्पादन के दौरान विभिन्न लंबाई के कई शून्य भरे हुए सरणियों को बनाने की आवश्यकता है, तो मैंने इसे प्राप्त करने का सबसे तेज़ तरीका एक बार शून्य सरणी बनाना है। , इस विषय पर बताए गए तरीकों में से एक का उपयोग करके, लंबाई जो आपको पता है कि कभी भी पार नहीं किया जाएगा, और फिर उस सरणी को आवश्यक रूप से टुकड़ा करें।

उदाहरण के लिए (सरणी को इनिशियलाइज़ करने के लिए ऊपर दिए गए उत्तर से फ़ंक्शन का उपयोग करके), अधिकतम लंबाई का एक शून्य भरा हुआ सरणी बनाएँ , कोड के लिए दृश्यमान चर के रूप में जिसे शून्य सरणियों की आवश्यकता होती है:

var zero = newFilledArray(maxLength, 0);

अब इस एरे को हर बार स्लाइस करें, इसके लिए आपको आवश्यक लम्बाई के एक शून्य भरे हुए एलीवेटर की आवश्यकता है < maxLength :

zero.slice(0, requiredLength);

मैं अपने कोड के निष्पादन के दौरान हजारों बार शून्य भरे हुए सरणियों का निर्माण कर रहा था, इससे प्रक्रिया में काफी तेजी आई।


13
function zeroFilledArray(size) {
    return new Array(size + 1).join('0').split('');
}

3
तुम भी new Array(size+1).join("x").split("x").map(function() { return 0; })वास्तविक संख्या पाने के लिए उपयोग कर सकते हैं
युवावस्था

6
@ युवल या सिर्फnew Array(size+1).join('0').split('').map(Number)
पॉल

11

मेरे पास नापसंद करने का कोश्ई कारण नहीं है:

Array.apply(null, Array(5)).map(Number.prototype.valueOf,0);
new Array(5+1).join('0').split('').map(parseFloat);

Zertosh द्वारा सुझाव दिया गया है, लेकिन एक नए ES6 सरणी एक्सटेंशन में आप इसे मूल रूप से fillविधि के साथ कर सकते हैं । अब IE एज, क्रोम और एफएफ इसका समर्थन करते हैं, लेकिन संगतता तालिका की जांच करें

new Array(3).fill(0)आपको दे देंगे [0, 0, 0]। आप किसी भी मान new Array(5).fill('abc')( जैसे ऑब्जेक्ट और अन्य सरणियों) के साथ सरणी को भर सकते हैं ।

उसके शीर्ष पर आप पिछली सरणियों को भरने के साथ संशोधित कर सकते हैं:

arr = [1, 2, 3, 4, 5, 6]
arr.fill(9, 3, 5)  # what to fill, start, end

जो आपको देता है: [1, 2, 3, 9, 9, 6]


10

जिस तरह से मैं आमतौर पर यह करता हूं (और आश्चर्यजनक तेज है) का उपयोग कर रहा है Uint8Array। उदाहरण के लिए, 1M तत्वों का शून्य भरा वेक्टर बनाना:

  var zeroFilled = [].slice.apply(new Uint8Array(1000000))

मैं एक लिनक्स उपयोगकर्ता हूं और हमेशा मेरे लिए काम किया है, लेकिन एक बार मैक का उपयोग करने वाले एक दोस्त के पास कुछ गैर-शून्य तत्व थे। मैंने सोचा कि उसकी मशीन खराब थी, लेकिन फिर भी यहाँ सबसे सुरक्षित तरीका है जिसे हमने ठीक किया है:

  var zeroFilled = [].slice.apply(new Uint8Array(new Array(1000000)) 

संपादित

क्रोम 25.0.1364.160

  1. फ्रेडरिक गोटलिब - 6.43
  2. सैम बरनम - 4.83
  3. एली - 3.68
  4. जोशुआ 2.91
  5. मैथ्यू क्रुमले - 2.67
  6. bduran - 2.55
  7. एलन राइस - 2.11
  8. कंगैक्स - 0.68
  9. TJ। क्राउडर - 0.67
  10. ज़र्टोश - एरोर

फ़ायरफ़ॉक्स 20.0

  1. एलन चावल - 1.85
  2. जोशुआ - 1.82
  3. मैथ्यू क्रुमले - 1.79
  4. bduran - 1.37
  5. फ्रेडरिक गोटलिब - 0.67
  6. सैम बरनम - 0.63
  7. एली - 0.59
  8. कगैक्स - 0.13
  9. TJ। क्राउडर - 0.13
  10. ज़र्टोश - एरोर

सबसे महत्वपूर्ण परीक्षण (मेरे लिए कम से कम) गुम: नोड एक। मुझे शक है कि यह क्रोम बेंचमार्क के करीब है।


यह मेरी उंगलियों के लिए, और मेरी आंखों के लिए सबसे कुशल तरीका है। लेकिन यह क्रोम के लिए बहुत धीमा है (उस jsperf के अनुरूप। 99% धीमा)।
Orwellophile

1
मुझे आश्चर्य है कि अगर आपके मित्र के मैक पर समस्या का संबंध है: stackoverflow.com/questions/39129200/… या शायद Array.slice UInt8Array को हैंडल नहीं कर रहा था और अनैतिक स्मृति को लीक कर रहा था? (एक सुरक्षा मुद्दा!)।
रोबोकट

@robocat अच्छी पकड़! अगर मुझे यह अच्छी तरह से याद है कि हम Node.js 0.6 या 0.8 का उपयोग कर रहे थे। हमने कुछ प्रकार के लीक के बारे में सोचा था लेकिन हम इसे उत्पादन स्टैक के साथ पुन: पेश नहीं कर सके इसलिए हमने इसे अनदेखा करने का निर्णय लिया।
दुरम

10

लॉश या अंडरस्कोर का उपयोग करना

_.range(0, length - 1, 0);

या यदि आपके पास एक सरणी मौजूद है और आप उसी लंबाई की एक सरणी चाहते हैं

array.map(_.constant(0));

तो खुशी है कि आपने इस उत्तर को जोड़ा, जैसा कि मैं अंडरस्कोर का उपयोग करता हूं, और मुझे पता था कि इसके लिए कुछ था ... लेकिन अभी तक इसे खोजने में सक्षम नहीं था। मैं बस यही चाहता हूं कि मैं इस का उपयोग करके वस्तुओं के सरणियों का निर्माण कर
सकूं

@ पांडा_दे। अरेंज (0, लंबाई -1, 0) .मैप (ऑब्जेक्ट.न्यू), मुझे लगता है।
djechlin

होना चाहिए _.range(0, length, 0), मुझे विश्वास है। लोदश अंतिम मूल्य का अनन्य है
user4815162342


8

के रूप में ECMAScript2016 , वहाँ बड़े सरणियों के लिए एक स्पष्ट विकल्प है।

चूँकि यह उत्तर अभी भी Google खोजों पर शीर्ष के पास दिखाई देता है, यहाँ 2017 के लिए एक उत्तर है।

इस प्रश्न पर अब तक प्रस्तावित कई दर्जन लोकप्रिय तरीकों के साथ एक वर्तमान jsbench है , जिसमें कई प्रस्तावित हैं। यदि आप एक बेहतर तरीका ढूंढते हैं तो कृपया जोड़ें, कांटा और साझा करें।

मैं यह नोट करना चाहता हूं कि एक मनमाना लंबाई शून्य भरा सरणी बनाने का कोई सच्चा सबसे कुशल तरीका नहीं है। आप गति, या स्पष्टता और स्थिरता के लिए अनुकूलन कर सकते हैं - या तो परियोजना की जरूरतों के आधार पर अधिक कुशल विकल्प माना जा सकता है।

गति के लिए अनुकूलन करते समय, आप चाहते हैं: शाब्दिक सिंटैक्स का उपयोग करके सरणी बनाएं; लंबाई सेट करें, पुनरावृति चर को इनिशियलाइज़ करें, और थोड़ी देर लूप का उपयोग करके सरणी के माध्यम से पुनरावृति करें। यहाँ एक उदाहरण है।

const arr = [];
arr.length = 120000;
let i = 0;
while (i < 120000) {
  arr[i] = 0;
  i++;
}

एक और संभावित कार्यान्वयन होगा:

(arr = []).length = n;
let i = 0;
while (i < n) {
    arr[i] = 0;
    i++;
}

लेकिन मैं दृढ़ता से इस दूसरे आरोपण का उपयोग कर हतोत्साहित करता हूं क्योंकि यह कम स्पष्ट है और आपको अपने सरणी चर पर ब्लॉक स्कूपिंग को बनाए रखने की अनुमति नहीं देता है।

लूप के लिए भरने की तुलना में ये काफी तेज हैं, और मानक विधि की तुलना में लगभग 90% तेज है

const arr = Array(n).fill(0);

लेकिन यह भरने की विधि अभी भी स्पष्टता, संक्षिप्तता और स्थिरता के कारण छोटे सरणियों के लिए सबसे कुशल विकल्प है। जब तक आप हजारों या अधिक के क्रम पर लम्बाई के साथ बहुत सारे सरणियाँ नहीं बना लेते, प्रदर्शन अंतर संभवत: आपको नहीं मारेंगे।

कुछ अन्य महत्वपूर्ण नोट। अधिकांश स्टाइल गाइड आपको सलाह देते हैं varकि ES6 या बाद में उपयोग करते समय आप किसी विशेष कारण के बिना उपयोग न करें । constउन चरों का उपयोग करें जिन्हें पुनर्परिभाषित नहीं किया जाएगा और जो चरों के लिए उपयोग किया letजाएगा। MDN और Airbnb की स्टाइल गाइड महान सर्वोत्तम प्रथाओं पर अधिक जानकारी के लिए जाने के लिए हैं। प्रश्न वाक्यविन्यास के बारे में नहीं था, लेकिन यह महत्वपूर्ण है कि पुराने और नए उत्तरों के इन स्थानों के माध्यम से खोज करने पर JS के नए लोग इन नए मानकों के बारे में जानते हैं।


8

एक नया ऐरे बनाने के लिए

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)]);


6

इस विधि को उत्तरों में नहीं देखा, इसलिए यहाँ यह है:

"0".repeat( 200 ).split("").map( parseFloat )

परिणाम में आपको लंबाई 200 की शून्य-मूल्यवान सरणी मिलेगी:

[ 0, 0, 0, 0, ... 0 ]

मैं इस कोड के प्रदर्शन के बारे में निश्चित नहीं हूं, लेकिन अगर आप इसे अपेक्षाकृत छोटे सरणियों के लिए उपयोग करते हैं तो यह एक मुद्दा नहीं होना चाहिए।


5
समाधानों की विविधता के लिए न तो सबसे तेज़ और न ही सबसे छोटा लेकिन एक अच्छा योगदान।
7vujy0f0hy

5

const arr = Array.from({ length: 10 }).fill(0)


1
यह शून्य के साथ सरणी को नहीं भरता है। यह इसे अपरिभाषित से भर देता है।
jlh

@ जेएलएच धन्यवाद तय
एलेक्स डाइकियों

4

concatChrome (2013-03-21) पर मेरे परीक्षणों में यह संस्करण बहुत तेज़ है। सीधे init के लिए लगभग 200ms 10,000,000 तत्वों बनाम 675 के लिए।

function filledArray(len, value) {
    if (len <= 0) return [];
    var result = [value];
    while (result.length < len/2) {
        result = result.concat(result);
    }
    return result.concat(result.slice(0, len-result.length));
}

बोनस: यदि आप स्ट्रिंग्स के साथ अपने एरे को भरना चाहते हैं, तो यह एक संक्षिप्त तरीका है इसे करने के लिए ( concatहालांकि उतना तेज़ नहीं है ):

function filledArrayString(len, value) {
    return new Array(len+1).join(value).split('');
}

2
ठीक है, जंगली। यह नया ऐरे (लेन) का उपयोग करने की तुलना में तेज़ है। परंतु! मैं क्रोम में देख रहा हूं कि बाद में उस डेटा को पढ़ता है जो काफी अधिक समय लेता है। यहां कुछ टाइमस्टैम्प दिखाए गए हैं कि मेरा क्या मतलब है: (नए ऐरे (लेन) का उपयोग करके) 0.365: एरे बनाना 4.526: कन्वोकेशन कन्वर्सेशन 10.75: कन्वेंसिंग कंप्लीट (कॉनसेट का उपयोग करते हुए) 0.339: एरियर 0.591 बनाना: एक्सक्लूसिव कन्वर्सेशन // OMG, WAY तेजी से 18.056: बातचीत पूर्ण
ब्रूक्स

4

मैं टीजे क्राउडर द्वारा दिए गए शानदार जवाब का परीक्षण कर रहा था, और क्रोम में उनके परीक्षणों में किसी भी आउटपरफॉर्म करने वाले कॉनकैट समाधान पर आधारित एक पुनरावर्ती मर्ज के साथ आया था (मैंने अन्य ब्राउज़रों का परीक्षण नहीं किया था)।

function makeRec(len, acc) {
    if (acc == null) acc = [];
    if (len <= 1) return acc;
    var b = makeRec(len >> 1, [0]);
    b = b.concat(b);
    if (len & 1) b = b.concat([0]);
    return b;
},

के साथ विधि को बुलाओ makeRec(29)



4

यह इंगित करने के लायक हो सकता है, जिसे ECMAScript 6 (हार्मनी) के प्रस्ताव केArray.prototype.fill हिस्से के रूप में जोड़ा गया था । मैं थ्रेड पर उल्लिखित अन्य विकल्पों पर विचार करने से पहले, नीचे लिखे पॉलीफ़िल के साथ जाना चाहूंगा।

if (!Array.prototype.fill) {
  Array.prototype.fill = function(value) {

    // Steps 1-2.
    if (this == null) {
      throw new TypeError('this is null or not defined');
    }

    var O = Object(this);

    // Steps 3-5.
    var len = O.length >>> 0;

    // Steps 6-7.
    var start = arguments[1];
    var relativeStart = start >> 0;

    // Step 8.
    var k = relativeStart < 0 ?
      Math.max(len + relativeStart, 0) :
      Math.min(relativeStart, len);

    // Steps 9-10.
    var end = arguments[2];
    var relativeEnd = end === undefined ?
      len : end >> 0;

    // Step 11.
    var final = relativeEnd < 0 ?
      Math.max(len + relativeEnd, 0) :
      Math.min(relativeEnd, len);

    // Step 12.
    while (k < final) {
      O[k] = value;
      k++;
    }

    // Step 13.
    return O;
  };
}

4

लूप कोड के लिए सबसे छोटा

a=i=[];for(;i<100;)a[i++]=0;

edit:
for(a=i=[];i<100;)a[i++]=0;
or
for(a=[],i=100;i--;)a[i]=0;

सुरक्षित संस्करण संस्करण

var a=[],i=0;for(;i<100;)a[i++]=0;

edit:
for(var i=100,a=[];i--;)a[i]=0;

2
यह देखते हुए कि लंबाई एक परिभाषित चर है, nयह कम होगा:for(var a=[];n--;a[n]=0);
टॉमस लैंगकास


3

मेरा सबसे तेज़ कार्य होगा:

function newFilledArray(len, val) {
    var a = [];
    while(len--){
        a.push(val);
    }
    return a;
}

var st = (new Date()).getTime();
newFilledArray(1000000, 0)
console.log((new Date()).getTime() - st); // returned 63, 65, 62 milliseconds

सरणी को घोषित करने और प्रत्येक आइटम को संदर्भित करने की तुलना में सरणी में आइटम जोड़ने के लिए देशी पुश और शिफ्ट का उपयोग सरणी में बहुत तेज (लगभग 10 गुना) है।

fyi: मैं लगातार पहले लूप के साथ तेज समय प्राप्त करता हूं, जो नीचे गिन रहा है, जब यह फायरबग (फ़ायरफ़ॉक्स एक्सटेंशन) में चल रहा है।

var a = [];
var len = 1000000;
var st = (new Date()).getTime();
while(len){
    a.push(0);
    len -= 1;
}
console.log((new Date()).getTime() - st); // returned 863, 894, 875 milliseconds
st = (new Date()).getTime();
len = 1000000;
a = [];
for(var i = 0; i < len; i++){
    a.push(0);
}
console.log((new Date()).getTime() - st); // returned 1155, 1179, 1163 milliseconds

मुझे यह जानने में दिलचस्पी है कि टीजे क्राउडर क्या बनाता है? :-)


आप इसे बदलकर इसे और तेज़ बना सकते हैं while (len--).. मेरी प्रोसेसिंग का समय लगभग 60ms से लेकर 54ms तक हो गया है
nicf

मैथ्यू Crumbly का जवाब अभी भी वास्तव में यह (30ms) धड़कता है!
निक

3

मुझे पता था कि मेरा यह प्रोटॉइड होगा कहीं :)

Array.prototype.init = function(x,n)
{
    if(typeof(n)=='undefined') { n = this.length; }
    while (n--) { this[n] = x; }
    return this;
}

var a = (new Array(5)).init(0);

var b = [].init(0,4);

संपादित करें: परीक्षण

जोशुआ और अन्य तरीकों के जवाब में मैंने अपना स्वयं का बेंचमार्किंग किया, और मैं उन रिपोर्ट के लिए पूरी तरह से अलग परिणाम देख रहा हूं।

यहाँ मैंने क्या परीक्षण किया है:

//my original method
Array.prototype.init = function(x,n)
{
    if(typeof(n)=='undefined') { n = this.length; }
    while (n--) { this[n] = x; }
    return this;
}

//now using push which I had previously thought to be slower than direct assignment
Array.prototype.init2 = function(x,n)
{
    if(typeof(n)=='undefined') { n = this.length; }
    while (n--) { this.push(x); }
    return this;
}

//joshua's method
function newFilledArray(len, val) {
    var a = [];
    while(len--){
        a.push(val);
    }
    return a;
}

//test m1 and m2 with short arrays many times 10K * 10

var a = new Date();
for(var i=0; i<10000; i++)
{
    var t1 = [].init(0,10);
}
var A = new Date();

var b = new Date();
for(var i=0; i<10000; i++)
{
    var t2 = [].init2(0,10);
}
var B = new Date();

//test m1 and m2 with long array created once 100K

var c = new Date();
var t3 = [].init(0,100000);
var C = new Date();

var d = new Date();
var t4 = [].init2(0,100000);
var D = new Date();

//test m3 with short array many times 10K * 10

var e = new Date();
for(var i=0; i<10000; i++)
{
    var t5 = newFilledArray(10,0);
}
var E = new Date();

//test m3 with long array created once 100K

var f = new Date();
var t6 = newFilledArray(100000, 0)
var F = new Date();

परिणाम:

IE7 deltas:
dA=156
dB=359
dC=125
dD=375
dE=468
dF=412

FF3.5 deltas:
dA=6
dB=13
dC=63
dD=8
dE=12
dF=8

तो मेरे रेकिंग पुश से वास्तव में धीमी गति से होता है, लेकिन एफएफ में लंबे समय तक सरणियों के साथ बेहतर प्रदर्शन करता है लेकिन आईई में इससे भी बदतर होता है जो सामान्य रूप से बेकार होता है (क्वेल आश्चर्य)।


मैंने अभी इसका परीक्षण किया है: दूसरी विधि ( b = []...) पहले की तुलना में 10-15% तेज है, लेकिन यह यहोशू के उत्तर की तुलना में 10 गुना अधिक धीमी है।
निकफ

मुझे पता है कि यह एक प्राचीन पद है । लेकिन शायद यह अभी भी दूसरों के लिए (मेरी तरह) ब्याज की है। इसलिए मैं प्रोटोटाइप फ़ंक्शन के लिए एक सुझाव देना चाहूंगा: -एक के else {this.length=n;}बाद शामिल करें this.length। यदि आवश्यक हो तो initइसे पहले से मौजूद सरणी को छोटा कर दिया जाएगा, जब इसे अलग लंबाई में पुन: लागू किया जाएगा n
कारों 10m

2

अनाम फ़ंक्शन:

(function(n) { while(n-- && this.push(0)); return this; }).call([], 5);
// => [0, 0, 0, 0, 0]

लूप के साथ थोड़ा छोटा:

(function(n) { for(;n--;this.push(0)); return this; }).call([], 5);
// => [0, 0, 0, 0, 0]

किसी भी के साथ काम करता है Object, बस अंदर क्या है बदल जाते हैं this.push()

आप फ़ंक्शन को भी सहेज सकते हैं:

function fill(size, content) {
  for(;size--;this.push(content));
  return this;
}

इसका उपयोग करके कॉल करें:

var helloArray = fill.call([], 5, 'hello');
// => ['hello', 'hello', 'hello', 'hello', 'hello']

पहले से मौजूद सरणी में तत्वों को जोड़ना:

var helloWorldArray = fill.call(helloArray, 5, 'world');
// => ['hello', 'hello', 'hello', 'hello', 'hello', 'world', 'world', 'world', 'world', 'world']

प्रदर्शन: http://jsperf.com/zero-filled-array-creation/25

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.