diff --git a/README.md b/README.md index 145c307..6fdc898 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,16 @@ The search function has 2 overloads: ```javascript new BS(arrObj).search('20380a36-8777-43f7-a79e-65bdb53f4621', 'guid'); ``` +3. Value and key in case of the object with custom condition as following: +```javascript +function searchCustomIterator(item, target) { + return (target >= item.min && target <= item.max)? 0: target - item.min; // res>0 || res<0 +} +var arrObj = [{id: '1',min:1,max:6},{id:'2',min:5,max:6},{id:'3',min:7,max:9},{id:'4',min:10,max: 12}]; + +new BS(arrObj).search(5, searchCustomIterator); // {id:'2',min:5,max:6} +``` + ## Sorting Now you can sort the array in chaining mechanism. ```javascript @@ -92,4 +102,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. diff --git a/dist/js-binarysearch.js b/dist/js-binarysearch.js index 26bd18e..258ab29 100644 --- a/dist/js-binarysearch.js +++ b/dist/js-binarysearch.js @@ -1,5 +1,5 @@ /*! js-binarysearch - v1.0.2 - * Release on: 2016-05-29 + * Release on: 2016-07-27 * Copyright (c) 2016 Amgad Fahmi * Licensed MIT */ (function(root, factory) { @@ -31,6 +31,8 @@ var BS = function(array) { BS.prototype.search = function(target, key) { if (key && typeof key === 'string') { return this.searchObj(target, key); + } else if (typeof key === 'function') { + return this.searchCustom(target, key); } else if (typeof target === 'number') { return this.searchNum(target); } else if (typeof target === 'string') { @@ -87,6 +89,26 @@ BS.prototype.searchObj = function(target, key) { } }; +/* +* @param iterator(item, target) => (1 || 0 || -1) +*/ +BS.prototype.searchCustom = function(target, iterator) { + var min = 0, + max = this.internalArray.length - 1, + temp, mid; + while (min <= max) { + mid = Math.round(min + (max - min) / 2); + temp = iterator(this.internalArray[mid], target); + if (temp === 0) { // temp match to target + return this.internalArray[mid]; + } else if (temp > 0) { + min = mid + 1; + } else { + max = mid - 1; + } + } +}; + BS.prototype.sort = function(key) { if (this.internalArray.length <= 1) { return; @@ -123,5 +145,6 @@ BS.prototype.sortNum = function() { return a - b; }); }; + return BS; })); diff --git a/dist/js-binarysearch.min.js b/dist/js-binarysearch.min.js index b6fbd51..385a8cc 100644 --- a/dist/js-binarysearch.min.js +++ b/dist/js-binarysearch.min.js @@ -1,5 +1,5 @@ /*! js-binarysearch - v1.0.2 - * Release on: 2016-05-29 + * Release on: 2016-07-27 * Copyright (c) 2016 Amgad Fahmi * Licensed MIT */ -!function(a,b){if("object"==typeof exports)module.exports=b(require,exports,module);else if("function"==typeof define&&define.amd)define(["require","exports","module"],b);else{var c=function(b){return a[b]},d=a,e={exports:d};a.BS=b(c,d,e)}}(this,function(a,b,c){"use strict";var d=function(a){if(!a)throw new error("Object is not defined");return this.internalArray=a,this};return d.prototype.search=function(a,b){return b&&"string"==typeof b?this.searchObj(a,b):"number"==typeof a?this.searchNum(a):"string"==typeof a?this.searchStr(a):void 0},d.prototype.searchNum=function(a){for(var b,c=0,d=this.internalArray.length-1;d>=c;){if(b=Math.round(c+(d-c)/2),this.internalArray[b]===a)return this.internalArray[b];this.internalArray[b]=c;){if(b=Math.round(c+(d-c)/2),this.internalArray[b]===a)return this.internalArray[b];this.internalArray[b]=e;){if(d=Math.round(e+(f-e)/2),c=this.internalArray[d]?this.internalArray[d][b]:void 0,c===a)return this.internalArray[d];a>c?e=d+1:f=d-1}},d.prototype.sort=function(a){if(!(this.internalArray.length<=1)){var b=a&&"string"==typeof a,c="number"==typeof this.internalArray[0];return b?(this.sortObj(a),this):c?(this.sortNum(),this):(this.internalArray.sort(),this)}},d.prototype.sortObj=function(a){var b="string"==typeof this.internalArray[0][a];b?this.internalArray.sort(function(b,c){return b[a].localeCompare(c[a])}):this.internalArray.sort(function(b,c){return b[a]-c[a]})},d.prototype.sortNum=function(){this.internalArray.sort(function(a,b){return a-b})},d}); \ No newline at end of file +!function(a,b){if("object"==typeof exports)module.exports=b(require,exports,module);else if("function"==typeof define&&define.amd)define(["require","exports","module"],b);else{var c=function(b){return a[b]},d=a,e={exports:d};a.BS=b(c,d,e)}}(this,function(a,b,c){"use strict";var d=function(a){if(!a)throw new error("Object is not defined");return this.internalArray=a,this};return d.prototype.search=function(a,b){return b&&"string"==typeof b?this.searchObj(a,b):"function"==typeof b?this.searchCustom(a,b):"number"==typeof a?this.searchNum(a):"string"==typeof a?this.searchStr(a):void 0},d.prototype.searchNum=function(a){for(var b,c=0,d=this.internalArray.length-1;c<=d;){if(b=Math.round(c+(d-c)/2),this.internalArray[b]===a)return this.internalArray[b];this.internalArray[b]0?e=d+1:f=d-1}},d.prototype.sort=function(a){if(!(this.internalArray.length<=1)){var b=a&&"string"==typeof a,c="number"==typeof this.internalArray[0];return b?(this.sortObj(a),this):c?(this.sortNum(),this):(this.internalArray.sort(),this)}},d.prototype.sortObj=function(a){var b="string"==typeof this.internalArray[0][a];b?this.internalArray.sort(function(b,c){return b[a].localeCompare(c[a])}):this.internalArray.sort(function(b,c){return b[a]-c[a]})},d.prototype.sortNum=function(){this.internalArray.sort(function(a,b){return a-b})},d}); \ No newline at end of file diff --git a/lib/js-binarysearch.js b/lib/js-binarysearch.js index ca27cb8..125035f 100644 --- a/lib/js-binarysearch.js +++ b/lib/js-binarysearch.js @@ -13,6 +13,8 @@ var BS = function(array) { BS.prototype.search = function(target, key) { if (key && typeof key === 'string') { return this.searchObj(target, key); + } else if (typeof key === 'function') { + return this.searchCustom(target, key); } else if (typeof target === 'number') { return this.searchNum(target); } else if (typeof target === 'string') { @@ -69,6 +71,29 @@ BS.prototype.searchObj = function(target, key) { } }; +/* +* @param iterator(item, target) => (1 || 0 || -1) +* iterator(item, target) => 1 => target is bigger +* iterator(item, target) => 0 => target found +* iterator(item, target) => -1 => target is smaller +*/ +BS.prototype.searchCustom = function(target, iterator) { + var min = 0, + max = this.internalArray.length - 1, + temp, mid; + while (min <= max) { + mid = Math.round(min + (max - min) / 2); + temp = iterator(this.internalArray[mid], target); + if (temp === 0) { // temp match to target + return this.internalArray[mid]; + } else if (temp > 0) { + min = mid + 1; + } else { + max = mid - 1; + } + } +}; + BS.prototype.sort = function(key) { if (this.internalArray.length <= 1) { return; @@ -104,4 +129,4 @@ BS.prototype.sortNum = function() { this.internalArray.sort(function(a, b) { return a - b; }); -}; \ No newline at end of file +}; diff --git a/spec/mainSpec.js b/spec/mainSpec.js index 43fc8da..12635cf 100644 --- a/spec/mainSpec.js +++ b/spec/mainSpec.js @@ -81,5 +81,25 @@ define(['BS'], function(BS) { }); }); + describe("Search", function() { + it("search by custom-iterator", function() { + function searchCustomIterator(item, target) { + if (target >= item.min && target <= item.max) { + return 0; // This is the item we want to find + } + + return target - item.min; // res>0 || res<0 + } + var arr = [ + {id: 33, name: 'Jasmin', min: 1, max: 6}, + {id: 12, name: 'David', min: 5, max: 6}, + {id: 7, name: 'Amgad', min: 7, max: 9}, + {id: 56, name: 'Katya', min: 10, max: 12} + ]; + var bs = new BS(arr).sort('min').search(5, searchCustomIterator); + expect(bs).toEqual({id: 12, name: 'David', min: 5, max: 6}); + }); + }); + }); console.log('Test ended ...'); \ No newline at end of file