UNPKG

basicprimitives

Version:

Basic Primitives Diagrams for JavaScript - data visualization components library that implements organizational chart and multi-parent dependency diagrams, contains implementations of JavaScript Controls and PDF rendering plugins.

75 lines (71 loc) 2.49 kB
/** * Callback for finding distance for a collection item * * @callback funcDistance * @param {Object} item A collection item * @param {number} index An index of the collection item * @returns {number} Returns a distance for the item */ /** * @typedef {Object} BinarySearchResult * @property {number} index The index of the nearest item in the collection * @property {Object} item The nearest item */ /** * Search sorted list of elements for the nearest item. * * @param {Object[]} items - The collection of elements. * @param {funcDistance} callback - A callback function to get distance for the collection item. * @param {number} [startMinimum=undefined] - The minimum index in the array to start search from * @param {number} [startMaximum=undefined] - The maximum index in the array to start search from * @returns {BinarySearchResult} Returns an item of the collection, which is nearest to optimal measured by callback function */ export default function binarySearch(items, callback, startMinimum, startMaximum) { var result = null, distance, bestDistance, minimum = startMinimum || 0, maximum = startMaximum || (items.length - 1), middle, item; if (items.length > 0) { item = items[minimum]; result = { index: minimum, item: item }; distance = callback(item, minimum); if (distance > 0) { bestDistance = Math.abs(distance); item = items[maximum]; distance = callback(item, maximum); if (distance >= 0) { result = { index: maximum, item: item }; } else { distance = Math.abs(distance); if (bestDistance > distance) { bestDistance = distance; result = { index: maximum, item: item }; } while (minimum + 1 < maximum) { middle = Math.round((minimum + maximum) / 2.0); item = items[middle]; distance = callback(item, middle); if (distance === 0) { result = { index: middle, item: item }; break; } else { if (distance > 0) { minimum = middle; } else { maximum = middle; } distance = Math.abs(distance); if (bestDistance > distance) { bestDistance = distance; result = { index: middle, item: item }; } } } } } } return result; };