UNPKG

1.9 kBJavaScriptView Raw
1// Generated by CoffeeScript 1.7.1
2(function() {
3 var binary_interval_search;
4
5 module.exports = binary_interval_search = function(data, lo_bound_key, hi_bound_key, id_key, probe) {
6
7 /* Given `data`, three indexes, and a `probe`, perform a binary search through `data` to find into which
8 of the given intervals `probe` falls.
9
10 `data` must be a list of lists or objects with each entry representing an interval; intervals must not
11 overlap, and the intervals in `data` must be sorted in ascending ordered. There may be gaps between
12 intervals.
13
14 You must give the keys to the lower and upper boundaries, so that `data[ idx ][ lo_bound_key ]` yields the
15 first value and `data[ idx ][ hi_bound_key ]` the last value of each interval. `id_key` should be either
16 `null` or a key for an entry so that `data[ idx ][ id_key ]` yields the ID (or whatever info) you want to
17 retrieve with your search.
18
19 If a match is found, the result will be either the index of the matching interval, or, if `id_key` was
20 defined, `interval[ id_key ]`. If no match is found, `null` is returned.
21
22 With thx to http://googleresearch.blogspot.de/2006/06/extra-extra-read-all-about-it-nearly.html
23 */
24 var hi_bound, hi_idx, id_and_range, lo_bound, lo_idx, mid_idx;
25 lo_idx = 0;
26 hi_idx = data.length - 1;
27 while (lo_idx <= hi_idx) {
28 mid_idx = Math.floor((lo_idx + hi_idx) / 2);
29 id_and_range = data[mid_idx];
30 lo_bound = id_and_range[lo_bound_key];
31 hi_bound = id_and_range[hi_bound_key];
32 if ((lo_bound <= probe && probe <= hi_bound)) {
33 if (id_key != null) {
34 return id_and_range[id_key];
35 } else {
36 return mid_idx;
37 }
38 }
39 if (probe < lo_bound) {
40 hi_idx = mid_idx - 1;
41 } else {
42 lo_idx = mid_idx + 1;
43 }
44 }
45 return null;
46 };
47
48}).call(this);