I have an array of sequential timestamps. I need to grab the subset of the array that falls between a start and end time. A simplified example would look something like:
timestamps = [ 5,7,12,13,15,23 ];
startTime = 6;
endTime = 18;
Given the above example, what is the most efficient way of finding the index of the first and last timestamps that fall between the startTime and endTime?
A correct script would discover and return indexes 1 & 4 (timestamps[1], timestamps[4])
I could loop through the array and do a comparison, but is there a more efficient way?
EDIT :: My solution - Binary search :
(Coffeescript)
# Search ordered array for timestamps falling between 'start' & 'end'
getRangeBorderIndexes = (stack, start, end) ->
ar = []
ar[0] = getBorder( stack, start, "left" )
ar[1] = getBorder( stack, end, "right" )
return ar
# Use bisection (binary search) to find leftmost or rightmost border indexes
getBorder = (stack, value, side ) ->
mod1 = if side == "left" then 0 else -1
mod2 = if side == "left" then 1 else 0
startIndex = 0
stopIndex = stack.length - 1
middle = Math.floor( (stopIndex+startIndex)/2 )
while stack[middle] != value && startIndex < stopIndex
if value < stack[middle]
if value > stack[middle - 1] then return middle + mod1
stopIndex = middle - 1
else if value > stack[middle]
if value < stack[middle + 1] then return middle + mod2
startIndex = middle + 1
middle = Math.floor( (stopIndex+startIndex)/2 )
return if stack[middle] != value then -1 else middle
timestamps = [ 5,7,12,13,15,23 ]
startTime = 6
endTime = 18
getRangeBorderIndexes( timestamps, startTime, endTime) # returns [1,5]
@kennebec and @Shanimal gave great responses, especially if you are wanting a super simple method for grabbing a subset of an array. However I needed indexes of the sub array rather than the entire sub array. I did some testing, and the above example consistently takes about 7ms to find the borders of the sub array, even on an array with 10 million entries!
Thanks to @voithos for pointing me in the right direction. I also modified this code to create the solution above.