2013-08-24 21 views
5

पर पारित सरणी को पारित किया गया है, मैं एक फ़ंक्शन में 2 सरणी पास करता हूं और एक सरणी से दूसरे सरणी में एक विशिष्ट प्रविष्टि को स्थानांतरित करना चाहता हूं। MoveDatum फ़ंक्शन स्वयं underscorejs विधियों को अस्वीकार और फ़िल्टर करता है। मेरी समस्या यह है कि मूल सरणी बदले नहीं जाते हैं, जैसे कि मैं सरणी को मान के रूप में पास कर रहा था और संदर्भ के रूप में नहीं। विशिष्ट प्रविष्टि सही ढंग से स्थानांतरित हो जाती है, लेकिन जैसा कि मैंने कहा, प्रभाव केवल स्थानीय है। मूल सरणी बदलने के लिए मुझे क्या बदलना है?फ़ंक्शन

कॉल समारोह:

this.moveDatum(sourceArr, targetArr, id) 

समारोह में ही:

function moveDatum(srcDS, trgDS, id) { 
    var ds = _(srcDS).filter(function(el) { 
     return el.uid === uid; 
    }); 
    srcDS = _(srcDS).reject(function(el) { 
     return el.uid === uid; 
    }); 
    trgDS.push(ds[0]); 
    return this; 
} 

मदद

+1

आप इसे '.filter() 'या' .reject()' के साथ नहीं कर सकते क्योंकि वे नए सरणी बनाते हैं। 'TrgDS.push (डीएस [0]) '(जैसे आप कर रहे हैं) के साथ' trgDS' को संशोधित करके आप 'targetArr' की सामग्री को बदल सकते हैं, क्योंकि दोनों एक ही सरणी को संदर्भित करते हैं, लेकिन आप' SourceArr' का कारण नहीं बना सकते एक नई सरणी में 'srcDS' असाइन करके एक नई सरणी का संदर्भ लें। – nnnnnn

+0

हो सकता है कि आप इस प्रश्न और स्पष्टीकरण उपयोगी पा सकते हैं: http://stackoverflow.com/questions/6605640/javascript-by-reference-vs-by-value – Stefan

+0

@nnnnnn धन्यवाद, मुझे लगता है कि अब मैं समझ क्या है चल रहा है, मूल रूप से मैं अस्वीकार() के साथ बनाई गई नई सरणी में srcDS का संदर्भ देता हूं और मूल रूप से पारित सरणी का संदर्भ खो देता हूं जिसे मैं वास्तव में बदलना चाहता हूं, क्या इसे ठीक करने का एक आसान तरीका होगा? – macg

उत्तर

2

कॉपी splice

function moveDatum(srcDS, trgDS, id) { // you pass an `id`, not `uid`? 
    var i; 
    for (i = 0; i < srcDS.length; ++i) { 
     if (srcDS[i].uid === uid) { 
      trgDS.push(srcDS[i]); 
      srcDS.splice(i, 1); 
      // optionally break here for just the first 
      i--; // remember; decrement `i` because we need to re-check the same 
       // index now that the length has changed 
     } 
    } 
    return this; 
} 
+0

धन्यवाद आप भी दोस्त = = – macg

+0

@macg अगर आपको लगता है कि पॉल का जवाब उपयोगी था तो कृपया इसे ऊपर उठाने पर विचार करें। – Stefan

+0

@Stefan मैंने इसे माना था, लेकिन स्टैक ओवरफ्लो मेरे साथ केवल 13 प्रतिष्ठा होने पर बहुत ही विचारशील नहीं है =) मुझे – macg

3

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

आप अपने सरणी संचालन, मूल सरणी पर सीधे प्रदर्शन करने के लिए शायद कुछ इस तरह की जरूरत है: इतना है कि आप के बारे में चिंता करने की ज़रूरत नहीं है

function moveDatum(srcDS, trgDS, id) { 
    var ds; 
    for (var i = srcDS.length - 1; i >= 0; i--) { 
     if (srcDS[i].uid === id) { 
      ds = srcDS[i]; 
      srcDS.splice(i,1); 
     } 
    } 
    trgDS.push(ds); 
    return this; 
} 

मैं पीछे की ओर जाने के लिए लूप को सेट कर लेने लूप इंडेक्स i सिंक से बाहर हो रहा है जब .splice() सरणी से आइटम हटा देता है। बैकवर्ड लूप का भी अर्थ है dssrcDS में पहले तत्व को संदर्भित करने के अंत में समाप्त होता है जो मेल खाता है, जो मुझे लगता है कि आपका मूल कोड trgDS.push(ds[0]) था।

आप को पता है कि सरणी ही कभी वास्तव में एक मैच होते हैं तो निश्चित रूप से यह कोई बात नहीं अगर आप आगे या पीछे की ओर जाना होगा होता है, और के बाद से वहाँ पाश जारी कोई मतलब नहीं है कि आप if अंदर एक break जोड़ सकते हैं एक बार आपके पास एक मैच है।

तरीकों जो सरणी, उदा संशोधित का उपयोग कर को हटाने से पहले (इसके अलावा मुझे लगता है कि आप एक टाइपो था, तो आप === id के बजाय === uid परीक्षण किया गया था।) हर मैच से अधिक

+0

धन्यवाद, एक आकर्षण की तरह काम करता है – macg