Getting around overuse of "if" statements.

조회 수: 3 (최근 30일)
Jacob Holmes
Jacob Holmes 2021년 7월 13일
댓글: Rik 2021년 7월 13일
I have a function which takes some data and adds it to an excel file. Depending on the inputs to the function, the data is put in different rows and columns of the excel file. The input is the day, week and site the data was recorded. My code is very clunky and just involves lots of "if" and elseif" statements which make the code hard to read and it takes ages to fix the code if something goes wrong. Is there a better way to write the following code?
function FileLocation(Data,Diff,DAY,SITE,WEEK)
if SITE == 'A'
if DAY == 'Mon'
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','C10:C14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','D10:D14')
elseif DAY == 'Tue'
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','E10:E14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','F10:F14')
elseif DAY == 'Wed'
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','G10:G14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','H10:H14')
elseif DAY == 'Thu'
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','I10:I14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','J10:J14')
else
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','K10:K14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','L10:L14')
end
end

채택된 답변

Rik
Rik 2021년 7월 13일
편집: Rik 2021년 7월 13일
You should use the value of DAY to set the value of a variable you can use as the range. You should also use strcmp to compare char arrays.
In this case you can use ismember:
function FileLocation(Data,Diff,DAY,SITE,WEEK)
if strcmp(SITE,'A')
filename = 'daily records.xlsx';
days={'Mon','Tue','Wed','Thu','Fri'};
LookUpTable={...
'C10:C14','D10:D14';...
'E10:E14','F10:F14';...
'G10:G14','H10:H14';...
'I10:I14','J10:J14';...
'K10:K14','L10:L14'};
L=ismember(days,DAY);
%you could check if sum(L) is 1 here if you like
Range=LookUpTable(L,:);
writematrix(Data,filename,'Sheet',WEEK,'Range',Range{1});
writematrix(Diff,filename,'Sheet',WEEK,'Range',Range{2});
end
The point is to make sure you are not repeating code. If you have code that you are calling mutliple times, you should either consider a loop or a function. A LUT can also be helpful to avoid repeating code.
  댓글 수: 5
Jacob Holmes
Jacob Holmes 2021년 7월 13일
I've done the following which works and seems quite neat to me:
function ExcelExport(Data,Diff,DAY,SITE,WEEK)
filename = 'testdata.xlsx'; % Name of the excel document
days={'Mon','Tue','Wed','Thu','Fri'}; % Matrix of week days to later compare
site = {'A','A','B','B','C','C'};
LookUpTable={... %Look up table for row and column destinations for data
'C10:C14','D10:D14','C16:C20','D16:D20','C22:C26','D22:D26';...
'E10:E14','F10:F14','E16:E20','F16:F20','E22:E26','F22:F26';...
'G10:G14','H10:H14','G16:G20','H16:H20','G22:G26','H22:H26';...
'I10:I14','J10:J14','I16:I20','J16:I20','I22:I26','J22:I26';...
'K10:K14','L10:L14','K16:K20','L16:L20','K22:K26','L22:L26'};
L=ismember(days,DAY); % Logical matrix. 0s everywhere apart from where matching day is gives 1
S = ismember(site,SITE);
%you could check if sum(L) is 1 here if you like
Range=LookUpTable(L,S);
writematrix(Data,filename,'Sheet',WEEK,'Range',Range{1});
writematrix(Diff,filename,'Sheet',WEEK,'Range',Range{2});
end
Rik
Rik 2021년 7월 13일
That's fine as well. You need to balance the chance of making a mistake when copy-pasting the LUT with the chance of making a mistake when writing the code that will generate the LUT. Case in point: my initial answer had 'I10:I14','I10:I14' instead of 'I10:I14','J10:J14'.

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Srinik Ramayapally
Srinik Ramayapally 2021년 7월 13일
Hey Jacob,
You can always use a switch-case instead of multiple if/else-if statements.
Here in this case, instead of the inner if/else-if statements, i suggest you to replace that code with this
switch DAY
case 'Mon'
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','C10:C14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','D10:D14')
case 'Tue'
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','E10:E14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','F10:F14')
case 'Wed'
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','G10:G14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','H10:H14')
case 'Thu'
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','I10:I14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','J10:J14')
otherwise
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','K10:K14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','L10:L14')
end
the case element can also accept multiple values like strings, cells etc.
Please refer to the switch,case,otherwise documentation for further reference.

Max Heiken
Max Heiken 2021년 7월 13일
I agree with Srinik Ramayapally, employing switch is the most obvious change that comes to mind. To extend on that solution, you could factor out the code common to all cases.
switch DAY
case 'Mon'
range1 = 'C10:C14';
range2 = 'D10:D14';
case 'Tue'
range1 = 'E10:E14';
range2 = 'F10:F14';
case 'Wed'
range1 = 'G10:G14';
range2 = 'H10:H14';
case 'Thu'
range1 = 'I10:I14';
range2 = 'J10:J14';
otherwise
range1 = 'K10:K14';
range2 = 'L10:L14';
end
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range',range1)
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range',range2)
To completely go without a switch, you could employ a Map object.
range1 = containers.Map({'Mon','Tue','Wed','Thu','Fri'},{'C10:C14','E10:E14','G10:G14','I10:I14','K10:K14'});
range2 = containers.Map({'Mon','Tue','Wed','Thu','Fri'},{'D10:D14','F10:F14','H10:H14','J10:J14','L10:L14'});
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range',range1(DAY))
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range',range2(DAY))
But notice that I had to assume here that "otherwise" always means "Fri". You could add more keys into the map that point to 'K10:K14'.
  댓글 수: 1
Jacob Holmes
Jacob Holmes 2021년 7월 13일
Thanks Max. That's a much better way of doing it.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Spreadsheets에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by