{"action":"created","issue":{"url":"https://api.github.com/repos/jashkenas/underscore/issues/2042","labels_url":"https://api.github.com/repos/jashkenas/underscore/issues/2042/labels{/name}","comments_url":"https://api.github.com/repos/jashkenas/underscore/issues/2042/comments","events_url":"https://api.github.com/repos/jashkenas/underscore/issues/2042/events","html_url":"https://github.com/jashkenas/underscore/pull/2042","id":57075700,"number":2042,"title":"Fixed bug in _.sortedIndex that put undefined at the start (FIX: #1834)","user":{"login":"arianf","id":7397857,"avatar_url":"https://avatars.githubusercontent.com/u/7397857?v=3","gravatar_id":"","url":"https://api.github.com/users/arianf","html_url":"https://github.com/arianf","followers_url":"https://api.github.com/users/arianf/followers","following_url":"https://api.github.com/users/arianf/following{/other_user}","gists_url":"https://api.github.com/users/arianf/gists{/gist_id}","starred_url":"https://api.github.com/users/arianf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arianf/subscriptions","organizations_url":"https://api.github.com/users/arianf/orgs","repos_url":"https://api.github.com/users/arianf/repos","events_url":"https://api.github.com/users/arianf/events{/privacy}","received_events_url":"https://api.github.com/users/arianf/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-02-09T19:15:03Z","updated_at":"2015-02-10T04:04:53Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/jashkenas/underscore/pulls/2042","html_url":"https://github.com/jashkenas/underscore/pull/2042","diff_url":"https://github.com/jashkenas/underscore/pull/2042.diff","patch_url":"https://github.com/jashkenas/underscore/pull/2042.patch"},"body":"Changed _.sortedIndex function to hangle undefined values correctly (FIXES: https://github.com/jashkenas/underscore/issues/1834 )\r\n\r\nRevised previous pull request: https://github.com/jashkenas/underscore/pull/2041\r\n\r\nPreviously \r\n\r\n```javascript\r\nif (iteratee(array[mid]) < value) low = mid + 1; else high = mid;\r\n```\r\n\r\nChanged it to:\r\n\r\n```javascript\r\nvar cur = iteratee(array[mid]);\r\nif ( cur < value || (value === void 0 && cur <= Infinity) || (_.isNaN(value) && (cur <= Infinity || cur === void 0))) low = mid + 1; else high = mid;\r\n```\r\n\r\n\r\nThe logic works because Undefined should be placed after the highest number possible + 1.\r\n\r\n```javascript\r\n(iteratee(array[mid]) <= Inifinity)\r\n// will always place undefined after the highest number, including Inifinity ( `<=` ).\r\n```\r\n\r\nBased on @jdalton request in https://github.com/jashkenas/underscore/pull/2041#issuecomment-73538789 I added `NaN` to always be placed after undefined.\r\nBased off of https://github.com/jashkenas/underscore/issues/1768#issuecomment-53900794 \r\n\r\n```javascript\r\n(_.isNaN(value) && (cur <= Infinity || cur === void 0)\r\n```\r\n\r\nThe code aboves logic checks to see if the value is NaN, if it is go past `Infinity` or `undefined`.\r\n\r\n```javascript\r\n\r\n_.sortedIndex([ 0, 10, 1000, undefined, NaN, NaN], undefined);\r\n// => 3\r\n\r\n_.sortedIndex([ 0, 10, 1000, undefined, NaN, NaN], NaN);\r\n// => 4\r\n```\r\n\r\nSo that how I built:\r\n\r\n```javascript\r\nvar cur = iteratee(array[mid]);\r\nif ( cur < value || (value === void 0 && cur <= Infinity) || (_.isNaN(value) && (cur <= Infinity || cur === void 0))) low = mid + 1; else high = mid;\r\n```\r\n\r\nSince no numeric value can be greater than Infinity, it will place undefined values to the correct index.\r\nAnd it will place all NaN past `Infinity` or `undefined`.\r\n\r\nAlso added edgeCaseTests, to verify it works:\r\n\r\n```javascript\r\ntest('sortedIndex conforms to sortBy for undefined (#1834)', function() {\r\n    var sorted = _.sortBy([undefined, 1, undefined, 2]);\r\n    equal(_.sortedIndex(sorted, undefined, _.identity), 2);\r\n\r\n    var edgeCaseNumbers = [-Infinity, -Infinity, 0, Number.MAX_VALUE, Infinity, Infinity, undefined, undefined, NaN];\r\n\r\n    var indexForUndefined = _.sortedIndex(edgeCaseNumbers, undefined);\r\n    equal(indexForUndefined, 6, 'undefined should be inserted at index 6');\r\n\r\n    var indexForNegInfinity = _.sortedIndex(edgeCaseNumbers, -Infinity);\r\n    equal(indexForNegInfinity, 0, 'negative infinity should be inserted at index 0');\r\n\r\n    var indexForInfinity = _.sortedIndex(edgeCaseNumbers, Infinity);\r\n    equal(indexForInfinity, 4, 'infinity should be inserted at index 4');\r\n\r\n    var indexForZero = _.sortedIndex(edgeCaseNumbers, 0);\r\n    equal(indexForZero, 2, '0 should be inserted at index 2');\r\n\r\n    var indexForNaN = _.sortedIndex(edgeCaseNumbers, NaN);\r\n    equal(indexForNaN, 8, 'NaN should be inserted at index 8');\r\n\r\n    var numbers = [10, 20, 30, 40, 50];\r\n\r\n    var indexForUndefinedSimple = _.sortedIndex(numbers, undefined);\r\n    equal(indexForUndefinedSimple, 5, 'undefined should be inserted at index 5');\r\n  });\r\n```"},"comment":{"url":"https://api.github.com/repos/jashkenas/underscore/issues/comments/73641085","html_url":"https://github.com/jashkenas/underscore/pull/2042#issuecomment-73641085","issue_url":"https://api.github.com/repos/jashkenas/underscore/issues/2042","id":73641085,"user":{"login":"arianf","id":7397857,"avatar_url":"https://avatars.githubusercontent.com/u/7397857?v=3","gravatar_id":"","url":"https://api.github.com/users/arianf","html_url":"https://github.com/arianf","followers_url":"https://api.github.com/users/arianf/followers","following_url":"https://api.github.com/users/arianf/following{/other_user}","gists_url":"https://api.github.com/users/arianf/gists{/gist_id}","starred_url":"https://api.github.com/users/arianf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arianf/subscriptions","organizations_url":"https://api.github.com/users/arianf/orgs","repos_url":"https://api.github.com/users/arianf/repos","events_url":"https://api.github.com/users/arianf/events{/privacy}","received_events_url":"https://api.github.com/users/arianf/received_events","type":"User","site_admin":false},"created_at":"2015-02-10T04:04:53Z","updated_at":"2015-02-10T04:04:53Z","body":"@megawac To make it work with #1882 what if I change the signature to include a last argument? ```javascript\r\n_.sortedIndex = function(array, obj, iteratee, context, last)\r\n```\r\nwhere if last is set to true, it will return the last"}}