2008-10-21 16 views
195

में परिवर्तित करने का सबसे प्रभावी तरीका क्या है HTML संग्रह को एक ऐरे में परिवर्तित करने का एक और अधिक प्रभावी तरीका है, जो कि संग्रहित सामग्री की सामग्री के माध्यम से पुन: सक्रिय करने और मैन्युअल रूप से प्रत्येक आइटम को सरणी में धक्का दे रहा है?एक HTMLCollection को एक ऐरे

+7

"कुशल" का क्या अर्थ है? यदि सबसे अच्छा प्रदर्शन होता है, तो * * * लूप के लिए आमतौर पर * Array.prototype.slice * से तेज़ होता है। एक लूप भी विभिन्न प्रकार के ब्राउज़रों (यानी सभी) में काम करता है, इसलिए उन मानदंडों से यह * सबसे प्रभावी तरीका है। और यह बहुत छोटा कोड है: 'के लिए (var a = [], i = collection.length; i;) एक [- i] = संग्रह [i];' इसलिए "con" में से अधिक नहीं है :-) – RobG

+0

@RobG धन्यवाद - अगर मैं कर सकता तो मैं आपको + 59k दूंगा! ;-) – Slashback

+0

[* वर्तमान ब्राउज़र प्रदर्शन *] (http://jsperf.com/slice-vs-loop-2016) पर देख रहे हैं, * स्लाइस * क्रोम को छोड़कर प्रदर्शन के संदर्भ में ज्यादातर लूप के साथ पकड़ा गया है। तत्वों की एक बड़ी संख्या और लूप के मामूली अनुकूलन का उपयोग करके, [* परिणाम लगभग समान *] (http://jsperf.com/slice-vs-loop/11) हैं, क्रोम को छोड़कर जहां एक लूप बहुत तेज है । – RobG

उत्तर

346
var arr = Array.prototype.slice.call(htmlCollection) 

"मूल" कोड का उपयोग कर एक ही प्रभाव होगा।

संपादित

के बाद से इस विचार, टिप्पणी (@ Oriol की टिप्पणी के अनुसार) है जो निम्न अधिक संक्षिप्त अभिव्यक्ति प्रभावी रूप से बराबर है की एक बहुत कुछ हो जाता है:

var arr = [].slice.call(htmlCollection); 

लेकिन @ JussiR के प्रति ध्यान दें टिप्पणी, "वर्बोज़" फ़ॉर्म के विपरीत, यह प्रक्रिया में एक खाली, अप्रयुक्त, और वास्तव में अनुपयोगी सरणी उदाहरण बनाता है। इसके बारे में क्या कंपाइलर प्रोग्रामर के केन के बाहर है।

संपादित

के बाद से ECMAScript 2015 (एड 6) भी Array.from वहाँ है: क्रॉस ब्राउज़र कार्यान्वयन के लिए

var arr = Array.from(htmlCollection); 
+5

देखें यह IE – KooiInc

+6

में काम नहीं करता है यह IE6 में विफल रहता है। –

+5

[काम नहीं करता] [http://jsfiddle.net/P7j98/) इंटरनेट एक्सप्लोरर ** 8 ** तक। –

5

मैं sugguest चाहते हैं आप prototype.js$A समारोह को देखने के

copyed from 1.6.1 :

function $A(iterable) { 
    if (!iterable) return []; 
    if ('toArray' in Object(iterable)) return iterable.toArray(); 
    var length = iterable.length || 0, results = new Array(length); 
    while (length--) results[length] = iterable[length]; 
    return results; 
} 

यह Array.prototype.slice का उपयोग नहीं करता है क्योंकि यह हर ब्राउज़र पर उपलब्ध नहीं है। मुझे डर है कि प्रदर्शन बहुत खराब है क्योंकि पतन वापस iterable पर एक जावास्क्रिप्ट पाश है।

+2

ओपी ने "संग्रहित सामग्री की सामग्री के माध्यम से पुनरावृत्त करने और मैन्युअल रूप से प्रत्येक आइटम को सरणी में धक्का देने" की तुलना में एक अन्य तरीके से पूछा, लेकिन यह वही है जो '$ ए' फ़ंक्शन ज्यादातर समय करता है। – Luc125

+1

मुझे लगता है कि जिस बिंदु को मैं बनाने की कोशिश कर रहा था वह यह है कि ऐसा करने का कोई अच्छा तरीका नहीं है, प्रोटोटाइप.जेएस कोड दिखाता है कि आप 'toArray' विधि की तलाश कर सकते हैं, लेकिन यह सुनिश्चित करने में असफल रहा कि सबसे सुरक्षित मार्ग –

+1

स्पैस सरणी में नए, अपरिभाषित सदस्य। असाइनमेंट से पहले * hasOwnProperty * परीक्षण होना चाहिए। – RobG

2

यह मेरा व्यक्तिगत समाधान, जानकारी यहां (इस सूत्र) पर आधारित है:

var Divs = new Array();  
var Elemns = document.getElementsByClassName("divisao"); 
    try { 
     Divs = Elemns.prototype.slice.call(Elemns); 
    } catch(e) { 
     Divs = $A(Elemns); 
    } 

कहाँ $ एक गैरेथ डेविस द्वारा वर्णित किया गया था अपनी पोस्ट में:

function $A(iterable) { 
    if (!iterable) return []; 
    if ('toArray' in Object(iterable)) return iterable.toArray(); 
    var length = iterable.length || 0, results = new Array(length); 
    while (length--) results[length] = iterable[length]; 
    return results; 
} 

ब्राउज़र का समर्थन करता है सबसे अच्छा तरीका, ठीक है, अन्यथा क्रॉस ब्राउज़र का उपयोग करेंगे।

+0

सामान्य रूप से, मैं नियंत्रण प्रवाह को प्रबंधित करने के लिए एक कुशल तरीका होने की कोशिश/पकड़ने की अपेक्षा नहीं करता हूं।आप जांच सकते हैं कि फ़ंक्शन पहले मौजूद है या नहीं, फिर एक या दूसरे को थोड़ा सस्ता चलाएं। – Patrick

+2

गैरेथ डेविस के जवाब के साथ, यह स्पैस सरणी में नए, अपरिभाषित सदस्यों को बनाता है, इसलिए '[,]' 'बन जाता है [अपरिभाषित, अपरिभाषित]'। – RobG

+0

मुझे अभी तक इस तरह की परेशानी नहीं मिली है। यह 2 तत्वों के साथ एक सरणी में एक 3 तत्व संग्रह परिणाम seams। चूंकि खाली खाली होने के लिए, यह जावास्क्रिप्ट की सीमाओं का एक सा है, मुझे लगता है कि आप अपरिभाषित की बजाय शून्य की उम्मीद कर रहे थे, है ना? – Gustavo

17

मैंने सामान्य रूप से Array.prototype विधियों को प्राप्त करने की एक और संक्षिप्त विधि देखी जो कि काम करता है। जैसा कि पहले टिप्पणी, ऐसे IE7 के रूप में पुराने ब्राउज़र के लिए में उल्लेख किया और

 
[].slice.call(yourHTMLCollectionObject); 

और,, आप बस, एक संगतता समारोह का उपयोग करने के की तरह: एक Array वस्तु में एक HTMLCollection वस्तु परिवर्तित नीचे बताया गया है

function toArray(x) { 
    for(var i = 0, a = []; i < x.length; i++) 
     a.push(x[i]); 

    return a 
} 

मुझे पता है कि यह एक पुराना सवाल है, लेकिन मुझे लगा कि स्वीकार्य उत्तर थोड़ा अपूर्ण था; इसलिए मैंने सोचा कि मैं इसे एफडब्ल्यूआईडब्ल्यू में फेंक दूंगा।

48

यकीन नहीं करता है, तो यह सबसे कारगर है, लेकिन एक संक्षिप्त ES6 वाक्य रचना हो सकता है:

let arry = [...htmlCollection] 

संपादित करें: एक और एक, Chris_F टिप्पणी से:

let arry = Array.from(htmlCollection) 
+6

इसके अतिरिक्त, ES6 'Array.from() ' –

+3

पहले के लिए देखें, बेबेल के साथ पार करते समय एक सूक्ष्म बग है जहां [... htmlCollection] HTMLCollection के साथ एक सरणी वापस कर देगा क्योंकि यह केवल तत्व है। –

+1

ऐरे फैल ऑपरेटर htmlCollection पर काम नहीं करता है। यह केवल नोडलिस्ट पर लागू है। – Bobby

2

इस में काम करता है पहले आईई संस्करणों सहित सभी ब्राउज़रों।

var arr = []; 
[].push.apply(arr, htmlCollection); 

चूंकि jsperf अभी भी इस समय नीचे है, यहां एक jsfiddle है जो विभिन्न विधियों के प्रदर्शन की तुलना करता है। https://jsfiddle.net/qw9qf48j/

संबंधित मुद्दे