|
@ -1193,56 +1193,37 @@ exports.binarySearchGeneric = function(orderedItems, target, field, sidePreferen |
|
|
var iteration = 0; |
|
|
var iteration = 0; |
|
|
var low = 0; |
|
|
var low = 0; |
|
|
var high = orderedItems.length - 1; |
|
|
var high = orderedItems.length - 1; |
|
|
var newLow = low; |
|
|
|
|
|
var newHigh = high; |
|
|
|
|
|
var prevValue, value, nextValue, middle; |
|
|
var prevValue, value, nextValue, middle; |
|
|
|
|
|
|
|
|
if (orderedItems.length == 0) { |
|
|
|
|
|
return -1; // did not find the target value
|
|
|
|
|
|
} |
|
|
|
|
|
else if (orderedItems.length == 1) { |
|
|
|
|
|
if (orderedItems[0][field] == target) {return 0;} // if the value matched the value we look for, return index 0
|
|
|
|
|
|
else {return -1;} |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
while (iteration < maxIterations) { |
|
|
|
|
|
// get a new guess
|
|
|
|
|
|
middle = Math.floor(0.5*(high+low)); |
|
|
|
|
|
prevValue = orderedItems[Math.max(0,middle - 1)][field]; |
|
|
|
|
|
value = orderedItems[middle][field]; |
|
|
|
|
|
nextValue = orderedItems[Math.min(orderedItems.length-1,middle + 1)][field]; |
|
|
|
|
|
|
|
|
|
|
|
if (value == target) { // we found the target
|
|
|
|
|
|
return middle; |
|
|
|
|
|
} |
|
|
|
|
|
else if (prevValue < target && value > target) { // target is in between of the previous and the current
|
|
|
|
|
|
return sidePreference == 'before' ? Math.max(0,middle - 1) : middle; |
|
|
|
|
|
} |
|
|
|
|
|
else if (value < target && nextValue > target) { // target is in between of the current and the next
|
|
|
|
|
|
return sidePreference == 'before' ? middle : Math.min(orderedItems.length-1,middle + 1); |
|
|
|
|
|
} |
|
|
|
|
|
else { // didnt find the target, we need to change our boundaries.
|
|
|
|
|
|
if (value < target) { // it is too small --> increase low
|
|
|
|
|
|
newLow = middle; |
|
|
|
|
|
} |
|
|
|
|
|
else { // it is too big --> decrease high
|
|
|
|
|
|
newHigh = middle; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
while (low <= high && iteration < maxIterations) { |
|
|
|
|
|
// get a new guess
|
|
|
|
|
|
middle = Math.floor(0.5*(high+low)); |
|
|
|
|
|
prevValue = orderedItems[Math.max(0,middle - 1)][field]; |
|
|
|
|
|
value = orderedItems[middle][field]; |
|
|
|
|
|
nextValue = orderedItems[Math.min(orderedItems.length-1,middle + 1)][field]; |
|
|
|
|
|
|
|
|
if (low == newLow && high == newHigh) { // if we did not find it and our new boundaries are the same as the old, the target is not in the list
|
|
|
|
|
|
return -1; |
|
|
|
|
|
} |
|
|
|
|
|
else { // we have new boundaries, lets use them!
|
|
|
|
|
|
high = newHigh; |
|
|
|
|
|
low = newLow; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (value == target) { // we found the target
|
|
|
|
|
|
return middle; |
|
|
|
|
|
} |
|
|
|
|
|
else if (prevValue < target && value > target) { // target is in between of the previous and the current
|
|
|
|
|
|
return sidePreference == 'before' ? Math.max(0,middle - 1) : middle; |
|
|
|
|
|
} |
|
|
|
|
|
else if (value < target && nextValue > target) { // target is in between of the current and the next
|
|
|
|
|
|
return sidePreference == 'before' ? middle : Math.min(orderedItems.length-1,middle + 1); |
|
|
|
|
|
} |
|
|
|
|
|
else { // didnt find the target, we need to change our boundaries.
|
|
|
|
|
|
if (value < target) { // it is too small --> increase low
|
|
|
|
|
|
low = middle + 1; |
|
|
|
|
|
} |
|
|
|
|
|
else { // it is too big --> decrease high
|
|
|
|
|
|
high = middle - 1; |
|
|
} |
|
|
} |
|
|
iteration++; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
iteration++; |
|
|
} |
|
|
} |
|
|
// didnt find anything. Return the last guess.
|
|
|
|
|
|
console.log("BinarySearchGeneric did too many iterations. Aborting."); |
|
|
|
|
|
return middle; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// didnt find anything. Return -1.
|
|
|
|
|
|
return -1; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|