2012-02-15 30 views
18

मान लीजिए कि मेरे पास एक स्ट्रक्चर सरणी arr है, जहां प्रत्येक तत्व में फ़ील्ड का समूह है, जिसमें val नामक एक भी शामिल है। मैं बहुत की तरह, कुछ निरंतर राशि से प्रत्येक तत्व के val क्षेत्र को बढ़ाने के लिए करना चाहते हैं:मैटलैब स्ट्रक्चर सरणी के प्रत्येक तत्व में एक फ़ील्ड अपडेट करना

for i = 1:length(arr) 
    arr(i).val = arr(i).val + 3; 
end 

यह स्पष्ट रूप से काम करता है, लेकिन मैं के लिए कोड की केवल एक पंक्ति में यह करने के लिए एक तरह से होना चाहिए लग रहा है (और कोई पाश)। सबसे अच्छा मैं दो लाइनों के साथ आया हूं और एक अस्थायी चर की आवश्यकता है:

newVals = num2cell([arr.val] + 3); 
[arr.val] = deal(newVals{:}); 

कोई विचार? धन्यवाद।

उत्तर

11

बस एक ध्यान दें, deal वहाँ आवश्यक नहीं है:

[arr.val] = newVals{:}; % achieves the same as deal(newVals{:}) 

केवल अन्य तरह से मैं कैसे (Foor पाश के बिना) यह करने के लिए पता arrayfun उपयोग कर रहा है सरणी में प्रत्येक struct से अधिक पुनरावृति करने के लिए :

% make a struct array 
arr = [ struct('val',0,'id',1), struct('val',0,'id',2), struct('val',0,'id',3) ] 

% some attempts 
[arr.val]=arr.val; % fine 
[arr.val]=arr.val+3; % NOT fine :(

% works ! 
arr2 = arrayfun(@(s) setfield(s,'val',s.val+3),arr) 

arr में प्रत्येक struct अंतिम ओवर आदेश छोरों और एक नया जहां s.vals.val=3 करने के लिए सेट कर दिया गया है देता है।

मुझे लगता है कि यह वास्तव में कम अपने पिछले दो लाइनर की तुलना में कुशल है और पाश के लिए हालांकि, क्योंकि यह देता है एक कॉपी arr की के रूप में जगह के संचालन के लिए विरोध किया।

(यह शर्म की बात है मैटलैब [arr.val]=num2cell([arr.val]+3){:} जैसे स्तरित अनुक्रमण का समर्थन नहीं करता है)।

+0

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

+0

इस उत्तर के लिए धन्यवाद! MATLAB 2013b में, [arr.val] = newVals {:} काम करता है लेकिन arr.val = newVals {:}। इस मामले में ब्रैकेट वास्तव में क्या करते हैं? –

+0

'arrayfun' MATLAB में 'फॉर' लूप के लिए सिर्फ एक रैपर है, इसलिए तकनीकी रूप से आप अभी भी छिपाने के बावजूद लूप का उपयोग कर रहे हैं। – Adriaan

1

क्या उस संरचना स्केलर, या एक ही आकार में सभी फ़ील्ड हैं? यदि ऐसा है, तो ऐसा करने के लिए idiomatic Matlab तरीका फ़ील्ड में स्केलर मानों के साथ structs की सरणी के बजाय, अपने प्रत्येक फ़ील्ड में सरणी के साथ एक स्केलर संरचना होने के लिए अपनी संरचना को पुनर्व्यवस्थित करना है। फिर आप arr.val = arr.val + 3; जैसे फ़ील्ड पर वेक्टरीकृत ऑपरेशन कर सकते हैं। देखें कि क्या आप अपना डेटा पुनर्व्यवस्थित कर सकते हैं। इसे इस तरह से करना समय और स्मृति दोनों में अधिक कुशल है; शायद यही कारण है कि Matlab structs के सरणी के क्षेत्रों पर परिचालन के लिए सुविधाजनक वाक्यविन्यास प्रदान नहीं करता है।

0

यदि struct सरणी आप स्थापित करने के लिए कोशिश कर रहे हैं ग्राफिक्स वस्तुओं (लाइन संभालती है, आंकड़ा हैंडल, हैंडल, आदि अक्ष), तो आप समारोह set उपयोग करने की आवश्यकता का एक सेट है:

x = (1:10)'; 
Y = rand(10,5); 
l = plot(x,Y,'-k'); % returns an array of line handles in l 
set(l,'Color','r'); % sets the property 'Color' for all the five lines in l