better way to code recursive if statements
I find myself in this position occasionally, and I'm sure there is a better way to do it than I am currently.
In this example, I'm trying to sort a group of times where I have conflicting items. I need to know what times are high-priority,can't be moved, vs low priority, can be moved. But I'm pretty sure this code is very inefficient.
var holdLowPriorities = [];
for (conflict = 0; conflict < sortedTimes.length - 1; conflict++) {
var firstConflictTimeStart = sortedTimes[conflict][0];
var firstConflictTimeEnd = sortedTimes[conflict][1];
var secondConflictTimeStart = sortedTimes[conflict + 1][0];
var secondConfl开发者_Go百科ictTimeEnd = sortedTimes[conflict + 1][1];
if (firstConflictTimeStart < secondConflictTimeEnd &&
firstConflictTimeEnd > secondConflictTimeStart) {
// are either of the conflicts a high priority
var firstContactPriority = sortedTimes[conflict][2];
var secondContactPriority = ortedTimes[conflict + 1][2]
if (firstConflictPriority == 2) {
//this is high priority, can't move
}
if (secondConflictPriority == 2) {
// this is also a priority, but has to move
}
// are either of the conflicts a low priority?
if (firstConflictPriority == 0) {
// this is a low priority so I can adjust the time
} else if (secondConflictPriority == 0) {
// this is a low priority so I can adjust the time
}
}
}
Unfortunately, I don't even know what to call this type of a problem, and therefore don't know what to look for, though I'm sure the answer isn't overly complicated (I hope not anyway).
A switch statement might help clean up your code a bit.
Edit: you've altered the question so most of this becomes irrelevant.
Here is a simple clarification of it.
var holdLowPriorities = [];
for(conflict=0; conflict<sortedTimes.length-1; conflict++){
var conflictTime = sortedTimes[conflict],
nextConflictTime = sortedTimes[conflict + 1];
if (conflictTime[0] >= nextConflictTime[1] || conflictTime[1] <= nextConflictTime[0]) {
continue;
}
// are either of the conflicts a high priority
if (data[conflictTime[2]].stepsArr[conflictTime[3]].priority==2) {
alert(data[conflictTime[2]].stepsArr[conflictTime[3]].
}
if (data[nextConflictTime[2]].stepsArr[nextConflictTime[3]].priority == 2) {
alert(data[nextConflictTime[2]].stepsArr[nextConflictTime[3]].
}
// are either of the conflicts a low priority?
if (data[conflictTime[2]].stepsArr[conflictTime[3]].priority==0) {
holdLowPriorities.push([conflictTime[2], conflictTime[3], conflict]);
} else if (data[nextConflictTime[2]].stepsArr[nextConflictTime[3]].priority == 0) {
holdLowPriorities.push([nextConflictTime[2], nextConflictTime[3], conflict+1])
}
//alert(data[nextConflictTime[2]].stepsArr[nextConflictTime[3]].prerequisite+' '+conflictTime[0]+' '+conflictTime[1]+' '+nextConflictTime[0]+' '+nextConflictTime[1]+' '+data[nextConflictTime[2]].stepsArr[nextConflictTime[3]].taskid+' / '+data[conflictTime[2]].stepsArr[conflictTime[3]].taskid);
}
Then this can be made more obvious by using a helper method and a couple more variables.
function conflictData(conflict) {
return data[conflict[2]].stepsArr[conflict[3];
}
var holdLowPriorities = [];
for(conflict=0; conflict<sortedTimes.length-1; conflict++){
var conflictTime = sortedTimes[conflict],
nextConflictTime = sortedTimes[conflict + 1];
if (conflictTime[0] >= nextConflictTime[1] || conflictTime[1] <= nextConflictTime[0]) {
continue;
}
var thisConflictData = conflictData(conflictTime),
nextConflictData = conflictData(nextConflictTime);
// are either of the conflicts a high priority
if (thisConflictData.priority == 2) {
alert(thisConflictData);
}
if (nextConflictData.priority == 2) {
alert(nextConflictData);
}
// are either of the conflicts a low priority?
if (thisConflictData.priority == 0) {
holdLowPriorities.push([conflictTime[2], conflictTime[3], conflict]);
} else if (nextConflictData.priority == 0) {
holdLowPriorities.push([nextConflictTime[2], nextConflictTime[3], conflict+1])
}
//alert(nextConflictData.prerequisite + ' ' + conflictTime[0] + ' ' + conflictTime[1] + ' ' + nextConflictTime[0] + ' ' + nextConflictTime[1] + ' ' + nextConflictData.taskid + ' / ' + thisConflictData.taskid);
}
When expressed like this, I think you can start to see probable bugs; high priority has conflictTime and nextConflictTime checks as if, if, whereas low priority has if, else if. Is this what is desired? You may be able to then put this/next conflict priority in a switch or reorganise the code more. But I think it's now at the stage where it can be understood more readily.
In terms of data structures, there is nothing inherently inefficiently with if..else blocks. Even nested if..else are not a problem. In terms of readability it's another matter altogether. As a rule of thumb, large and deeply nested if..else blocks are hard to follow (for a human, computers of course have no problems with them).
First of all, I'd go with Mitch's suggestion to use intermediate variables to reduce code verbosity. In terms of efficiency it is definitely less memory efficient (though for javascript, it could potentially speed up access depending on the browser). But efficiency is not the point, code clarity is.
Secondly, use array literal syntax instead of new Array()
: holdLowPriorities.push([...])
. Again, less noise on the screen, the easier it is to see what's going on.
Third, there are several places where all you're doing is checking the priority of something. Use either a helper function or a method to simplify the code here: checkProirity(sortedTimes,conflict,2)
or sortedTimes.checkProirity(conflict,2)
. Again, a function/method call is inherently less efficient but the point is to improve code clarity for good readability.
精彩评论