2012-03-29 16 views
7

करने के लिए कोड निम्नलिखित पर विचार करें:d2: बताए पर्वतमाला/iterators सरणी स्लाइस

enum size = 16; 
double[size] arr1 = [...]; 
double[size] arr2 = [...]; 
process = (double x) { return (x + 1); }; 

arr2[] = map!(process)(arr1[]); // here 

मैं अपने सादे सरणी map वापस की मुसीबत परिवर्तित परिणाम है। समस्या न केवल map पर लागू होती है, बल्कि take, repeat और std.algorithm और std.range से उन सभी ठीक उपकरण पर लागू होती है जो श्रेणियों पर चलती हैं।

इस असाइनमेंट पर, मुझे Error: cannot implicitly convert expression (map(arr1[])) of type Result to double[] मिलता है।

uint i = 0; 
foreach (x; map!(process)(arr1[])) { 
    arr2[i] = x; 
    i++; 
} 

का उपयोग किये बिना मैं श्रेणी को सरणी का मूल्यांकन कैसे कर सकता हूं?

इसके अतिरिक्त, क्या कोई कृपया समझा सकता है, मुझे map!(process)(arr1) के बजाय स्थिर arrays के साथ map!(process)(arr1[]) क्यों कॉल करना होगा? स्थैतिक सरणी पुनरावृत्ति के साधनों के लिए गतिशील के साथ संगत नहीं होना चाहिए, या मुझे कुछ नहीं मिला है?

इसके अलावा, ऐसा लगता है कि सीधा गणना वाक्यविन्यास foreach (index, item; sequence) श्रेणियों के लिए काम नहीं करता है - क्या कामकाज हैं? मुझे लगता है कि कारण वही है जैसे श्रेणियों को सरणी स्लाइस को असाइन नहीं किया जा सकता है। इस तरह के map और filter वापसी पर्वतमाला, नहीं सरणियों, तो बस एक सरणी के लिए बताए के रूप में

उत्तर

11

कार्य बताए एक stringwstring को काम करने के लिए जा रहा है की तुलना में किसी भी अधिक काम करने के लिए नहीं जा रहा है। वे अलग-अलग प्रकार हैं। और कई श्रेणी-आधारित कार्यों (map और filter समेत) के लिए, अनावश्यक गणना से बचने के लिए वे वापस लौटते हैं, जो उन्हें एक सरणी के साथ बहुत कम संगत बनाता है। समाधान std.array.array का उपयोग करना है, जो एक सीमा लेता है और इससे गतिशील सरणी बनाता है। तो, आप

auto arr = array(map!process(origArray)); 

हालांकि कर सकता है, मैं, एक सरणी में एक सीमा परिवर्तित नहीं सलाह होगा इससे पहले कि आप वास्तव में करने की जरूरत है क्योंकि यह अनावश्यक संगणना में परिणाम कर सकते हैं, और यह एक नई सरणी का आवंटन होता है। यदि आपको वास्तव में एक सरणी की आवश्यकता है, तो हर तरह से, श्रेणी को बदलने के लिए std.array.array का उपयोग करें, लेकिन यदि आपको वास्तविक सरणी की आवश्यकता नहीं है तो सीमा पर परिचालन अधिक कुशल हो सकता है। हालांकि, अगर आप के रूप में एक गतिशील एक जाने के बजाय किसी स्थिर सरणी के लिए परिणाम परिवर्तित करना चाहते हैं, तो आप शायद बेहतर बस एक पाश में प्रत्येक तत्व बताए (और शायद map पूरी तरह लंघन), कर रहे हैं का उपयोग कर के बाद से std.array.array तब एक गतिशील सरणी आवंटित की जाएगी जिसे आप स्थिर सरणी को सौंपने के बाद उपयोग नहीं करेंगे। यह स्मृति की बर्बादी है।

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

auto func() 
{ 
    int[5] arr; 
    return map!process(arr[]); 
} 

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

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

फिर सूचकांक और सीमाओं के साथ foreach का उपयोग कर, के बारे में सवाल का सवाल है, तो आप एक ही सवाल में कई सवाल नहीं पूछ किया जाना चाहिए। कृपया आपके पास प्रत्येक प्रश्न के लिए अलग-अलग प्रश्न पोस्ट करें। क्या यह हालांकि करने के लिए नीचे आता है कि

foreach(elem; range) 
{ 
    //stuff 
} 

for(; !range.empty; range.popFront()) 
{ 
    auto elem = range.front; 
    //stuff 
} 

के पास कुछ करने के लिए कम कर दिया जाता है और वह सूचकांकों बिल्कुल शामिल नहीं करता है। यह आप के लिए एक सूचकांक चर बनाने के लिए परिवर्तन हो सकता है, लेकिन यह हमेशा मतलब नहीं है पर्वतमाला है कि हर यात्रा (ज्यादा के रूप में यह आम तौर पर ठीक होगा) पर की तरह एक के बाद उनके सूचकांक बार-बार दोहराना है करने के लिए के लिए, और इतना है कि hasn नहीं किया गया है यद्यपि अपना खुद का काउंटर जोड़ने के लिए काफी आसान है।

{ 
    size_t i; 
    foreach(elem; range) 
    { 
     //stuff 
     ++i; 
    } 
} 

opApply foreach के साथ सूचकांक उपयोग करने का समर्थन करता है, लेकिन यह एक सीमा नहीं है, और सीमा आधारित कार्यों के साथ काम नहीं करता।

+0

धन्यवाद, जोनाथन! मुझे पता है कि श्रेणियां और सरणी अलग-अलग प्रकार हैं, लेकिन सोचा कि डी कुछ प्रकार के अंतर्निहित रूपांतरण को कार्यान्वित कर सकता है, क्योंकि श्रेणियां तब तक सरणी में परिवर्तनीय होती हैं जब तक कि वे परिमित हों और उनके तत्व सरणी के साथ संगत होते हैं। मुझे स्टैक और ढेर आवंटन, और सरणीकरण के गणना और स्मृति ओवरहेड के अंतर से अवगत है, लेकिन चेतावनी के लिए धन्यवाद :) इसके अलावा, आईएफटीआई के साथ इसे स्पष्ट करने के लिए धन्यवाद - अगर मुझे यह अधिकार समझ गया, तो भविष्य में यह बदल सकता है अंतर्निहित स्लाइसिंग स्थिर सरणी को अनुमति देने के लिए, लेकिन अब हमें अपूर्णता के कारण इस तरह का उपयोग करना चाहिए। – toriningen

+0

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

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