How do I use a struct as a function input?

2 ビュー (過去 30 日間)
mars
mars 2017 年 1 月 31 日
コメント済み: Stephen23 2017 年 4 月 13 日
I have a function that accepts up to 4 strings(they are 'rule1Before, rule1After, etc.' below) and in the the function these strings are set to struct values. In stead of hard coding these rules I would like to have one input, perhaps rules and then proceed as below. Any suggestions on how to handle this scenario? Thanks in advance!
function axiomGrowth = LsysExpand(rule1Before,rule1After,rule2Before,rule2After)
% LsysExpand: Expands from starting seed based on given parameters
% Inputs:
% numberOfIterations: number of times rules are applied
% axiom: the initial point from which growth occurs
% rule1Before: intital condition for rule 1
% rule1After: if rule1Before exists apply rule1After
% ...
% substituion rules
rule(1).before = rule1Before;
rule(1).after = rule1After;
% The arguments below are optional.
if nargin > 4
rule(2).before = rule2Before;
rule(2).after = rule2After;
end
  1 件のコメント
Stephen23
Stephen23 2017 年 4 月 13 日
Note to others: Do not use the accepted answer: it is buggy and very inefficient. See my answer for a much simpler, neater, and more efficient solution.

サインインしてコメントする。

採用された回答

mars
mars 2017 年 1 月 31 日
編集済み: mars 2017 年 2 月 4 日
rulesParsed = repmat(struct('before', {} ,'after', {} ), 2, 10);
ruleTracker = 1;
for i=1:length(rules)/2
if (mod(i,2)~=0)
rulesParsed(i).before = cellstr(rules(ruleTracker));
rulesParsed(i).after = cellstr(rules(ruleTracker+1));
ruleTracker=ruleTracker+2;
end
if (mod(i,2)==0)
rulesParsed(i).before = cellstr(rules(ruleTracker));
rulesParsed(i).after = cellstr(rules(ruleTracker+1));
ruleTracker=ruleTracker+2
end
end
  2 件のコメント
Stephen23
Stephen23 2017 年 2 月 4 日
編集済み: Stephen23 2017 年 4 月 13 日
This code has many bugs, and does not do what the author thinks it is doing: see my answer for a much more efficient solution.
For example the very first line seems to be an attempt at preallocating the output structure. However it does not work because the output structure is still empty:
>> repmat(struct('before', {} ,'after', {} ), 2, 10)
ans =
0x0 struct array with fields:
before
after
This means that the (initially empty!) structure will get expanded on each iteration: not an efficient use of memory. Also note that the author tries to preallocate to a different shape than the final output anyway (output is 3x1).
Then this code unnecessarily puts every string into a cell array:
>> tmp = rulesParsed(2).before
tmp =
'bef2'
>> class(tmp)
ans =
cell
>> tmp{1}
ans =
bef2
Why these 1xN chars are pointlessly put into cell arrays is not explained anywhere.
See my answer for a one line solution without all of these loops, ifs, bugs, pointless cell arrays, and inefficiency.
Guillaume
Guillaume 2017 年 2 月 4 日
編集済み: Guillaume 2017 年 2 月 6 日
Other issues:
if somecond
dosemething
end
if ~samecond
dosomethingelse
end
is better written as
if somecond
dosomething
else
dosomethingelse
end
But in this case, dosomething and dosomething else are identical, so the if serve no purpose.

サインインしてコメントする。

その他の回答 (1 件)

Stephen23
Stephen23 2017 年 2 月 4 日
編集済み: Stephen23 2017 年 2 月 4 日
Assuming that rules is a cell array of strings, then you just need this:
>> rules = {'bef1','aft1','bef2','aft2','bef3','aft3'};
>> rulesParsed = struct('before',rules(1:2:end),'after',rules(2:2:end))
That is all. Now lets test it:
>> rulesParsed(2).before
ans =
bef2
>> rulesParsed(2).after
ans =
aft2
Perfect. It produces the same structure as the OP's self-accepted answer, containing the same data. Just simpler, faster, and neater.

カテゴリ

Help Center および File ExchangeLoops and Conditional Statements についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by