2016-03-11 25 views
9

new Set() के लिए सुरक्षित कोड लग सकता है जैसे:ES6: सेट/मैप पुनरावृत्ति के दौरान सेट/मानचित्र से तत्वों को हटाना खतरनाक है?

let items = []; 
for (let item of set) 
    if (isBad(item)) 
    items.push(item); 
for (let item of items) 
    set.delete(item) 

मैं करने के लिए कोड को आसान बनाने में कर सकते हैं:

for (let item of set) 
    if (isBad(item)) 
    set.delete(item); 
new Map() के लिए

सुरक्षित कोड लग सकता है जैसे:

let keys = []; 
for (let [key, val] of map) 
    if (isBadKey(key) || isBadValue(val)) 
    keys.push(key); 
for (let key of keys) 
    map.delete(key) 

मैं करने के लिए कोड को आसान बनाने में कर सकते हैं :

for (let [key, val] of map) 
    if (isBadJey(key) || isBadValue(val)) 
    map.delete(key) 

उत्तर

6

हां, आप इसे सरल बना सकते हैं, यह पूरी तरह से सुरक्षित है।

  • सेट और मैप्स हमेशा प्रविष्टि आदेश
  • एक आइटम हटाया जा रहा है किसी भी इटरेटर की स्थिति को प्रभावित नहीं करता है में दोहराया जाता है - आप, संग्रह को बदला नहीं जा रहा है के आकार की कल्पना कर सकते सिर्फ खाली कर दिया जा रहा है।
  • तो: हटाए गए तत्व और अभी तक पुनरावृत्त नहीं किए गए हैं,
  • तत्व जो पहले से ही पुन: सक्रिय हो चुके हैं और हटाए गए हैं (जैसे आपके मामले में) अन्य पुनरावृत्तियों/लुकअप के अलावा कुछ भी प्रभावित नहीं करेंगे।
  • तत्वों कहा कि कर रहे हैं (और पहले से ही संग्रह का हिस्सा नहीं हैं) यात्रा के दौरान हमेशा

दोहराया जाएगा कि पिछले बिंदु से इस प्रकार है कि ऐसा करने के लिए केवल खतरनाक बात

const s = new Set([1]); 
for (let x of s) { 
    s.delete(x); 
    s.add(1); 
} 
की तरह कुछ होगा

लेकिन अपरिभाषित व्यवहार या स्मृति संचय की वजह से नहीं, बल्कि अनंत लूप की वजह से।

6

मैं हाँ कहूंगा, यह सुरक्षित है। जब आप हुड के नीचे for ... of का उपयोग करके सेट/मानचित्र पर फिर से चलते हैं तो लूप @@iterator से गुज़र रहा है। और Iterator केवल .next() के साथ संचालित है: इसलिए कोई सूचकांक और कोई फर्क नहीं पड़ता कि वर्तमान स्थिति से पहले क्या है। केवल एक अगला तत्व महत्वपूर्ण है।

तब तक जब तक आप मौजूदा इटरेटर स्थिति के सामने "तत्वों" को हटा नहीं देते - यह सुरक्षित है।

+0

क्या होगा यदि सेट() 'बाइनरी पेड़ के रूप में लागू किया गया हो? नोड को हटाने से वृक्ष फिर से संतुलन हो सकता है। क्या यह इटरेटर ऑपरेशन को नुकसान पहुंचाता है? – gavenkoa

+1

यह नहीं है। Spec के अनुसार - अंदर [सेट] (https://tc39.github.io/ecma262/#sec-set-iterable) एक [सूची] की तरह अधिक है (https://tc39.github.io/ecma262/#sec -सूची-और-रिकॉर्ड-विनिर्देश-प्रकार): 'सेट सेट [[SetData]] आंतरिक स्लॉट को एक नई खाली सूची में सेट करें।' – Kiril

+0

मुझे सूची की अवधि में 'सेट' का विवरण दिखाई देता है। तो क्या यह निष्पक्ष धारणा है कि 'सेट' 'ओ (लॉग 2 (आकार)) 'समय' में वास्तव में' ओ (आकार) 'में' हटाएं '/ 'add' /' है' है? – gavenkoa

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