2016-01-21 7 views
12

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

var array = []; 
 

 
for (var i = 0; i < 10; i++) { 
 
    array.push({ 
 
    value: i 
 
    }); 
 
} 
 

 
array.forEach(function(item, index, intArray) { 
 
    if (item.value % 2 == 1) { 
 
    item.odd = true; 
 
    } else { 
 
    item.odd = false; 
 
    } 
 

 
    if (item.odd) { 
 
    console.log("Removing " + item.value); 
 
    intArray.splice(index, 1); 
 
    } 
 

 
}); 
 

 
console.log(array);

अजीब तत्वों में यह जावास्क्रिप्ट परिणाम चल रहा है के रूप में उम्मीद हटाया जा रहा है, लेकिन यह भी intArray निकाला जा रहा है 2 आइटम, 4, 6, और 8 के लिए item.odd मान निकाल दिए। स्प्लिस लाइन अजीब सरणी तत्वों को वापस लाती है, लेकिन यह सभी तत्वों के लिए item.odd मान भी वापस लाती है।

मैंने इसे एफएफ और क्रोम में परीक्षण किया है। यह व्यवहार तब भी बनी रहती है जब कॉलबैक में केवल वस्तु को पास किया जाता है, इंडेक्स के साथ array.indexOf के माध्यम से गणना की जाती है, और लूप के बाहर से सरणी को संदर्भित किया जाता है।

+3

मुझे आश्चर्य है कि सरणी के साथ कुछ समस्या है जब आप इसे लूप कर रहे हैं। शायद 'इंडेक्स' मान मूल सरणी में सूचकांक है और नए संशोधित में नहीं है। –

+0

मेरे समान विचार थे। हालांकि, मुझे उम्मीद है कि उस मामले में बग आइटम और इंडेक्स अपेक्षित रूप से मेल नहीं खाएगा, इसलिए तत्वों के भीतर मूल्यों के बजाय बहुत सारे या बहुत कम तत्व हटा दिए जा रहे हैं। प्लस, अगर ऐसा होता तो मैं कॉलबैक में गुजरने वाले इंडेक्स के बीच एक अंतर के लिए देखता हूं और इसे फ्लाईट पर गणना करता हूं - लेकिन वे अभ्यास में भी काम करते हैं। –

उत्तर

9

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

var array = []; 
 

 
for (var i = 0; i < 10; i++) { 
 
    array.push({ 
 
    value: i 
 
    }); 
 
} 
 

 
array.forEach(function(item, index, intArray) { 
 
    console.log(item); // only prints out 0, 1, 3, 5, 7, 9 
 

 
    if (item.value % 2 == 1) { 
 
    item.odd = true; 
 
    } else { 
 
    item.odd = false; 
 
    } 
 

 
    if (item.odd) { 
 
    console.log("Removing " + item.value); 
 
    intArray.splice(index, 1); 
 
    } 
 

 
}); 
 

 
console.log(array);

दूसरे शब्दों में, forEach केवल एक सूचकांक एक बार दौरा किया। तो कहें कि यह आइटम 1 पर आता है, जो इंडेक्स 1 पर है। यह आइटम 1 हटा देता है। आइटम 2 अब इंडेक्स 1 पर है। लेकिन इंडेक्स 1 का पहले ही दौरा किया जा चुका है, इसलिए यह इंडेक्स 2 पर आइटम पर जाता है, जो अब आइटम है 3.

+1

यह समझाएगा कि '0' 'अजीब' संपत्ति वाला एकमात्र" यहां तक ​​कि "आइटम क्यों है। –

+0

कोड के माध्यम से दौड़ें - यह मेरे लिए सही लग रहा है। मुझे लगता है कि किसी को स्नैपशॉट पर परिचालन की सुविधा की अनुमति देने के बीच चयन करना होगा, जिससे सरणी के पुनरावृत्त संशोधन के लिए अनुमति मिल सकती है। –

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