index.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. exports.add = add
  2. exports.remove = remove
  3. exports.has = has
  4. exports.eq = eq
  5. exports.lte = lte
  6. exports.lt = lt
  7. exports.gte = gte
  8. exports.gt = gt
  9. exports.nearest = nearest
  10. function defaultCmp (a, b) {
  11. if (a === b) return 0
  12. return a > b ? 1 : -1
  13. }
  14. function add (list, value, cmp) {
  15. if (!cmp) cmp = defaultCmp
  16. var top = list.push(value) - 1
  17. while (top) {
  18. if (cmp(list[top - 1], value) < 0) return
  19. list[top] = list[top - 1]
  20. list[top - 1] = value
  21. top--
  22. }
  23. }
  24. function lte (list, value, cmp) {
  25. if (!cmp) cmp = defaultCmp
  26. var i = indexOf(list, value, cmp)
  27. if (i === -1) return -1
  28. for (; i >= 0; i--) {
  29. var c = cmp(list[i], value)
  30. if (c <= 0) return i
  31. }
  32. return -1
  33. }
  34. function lt (list, value, cmp) {
  35. if (!cmp) cmp = defaultCmp
  36. var i = indexOf(list, value, cmp)
  37. if (i === -1) return -1
  38. for (; i >= 0; i--) {
  39. var c = cmp(list[i], value)
  40. if (c < 0) return i
  41. }
  42. return -1
  43. }
  44. function gte (list, value, cmp) {
  45. if (!cmp) cmp = defaultCmp
  46. var i = indexOf(list, value, cmp)
  47. if (i === -1) return -1
  48. for (; i < list.length; i++) {
  49. var c = cmp(list[i], value)
  50. if (c >= 0) return i
  51. }
  52. return -1
  53. }
  54. function gt (list, value, cmp) {
  55. if (!cmp) cmp = defaultCmp
  56. var i = indexOf(list, value, cmp)
  57. if (i === -1) return -1
  58. for (; i < list.length; i++) {
  59. var c = cmp(list[i], value)
  60. if (c > 0) return i
  61. }
  62. return -1
  63. }
  64. function eq (list, value, cmp) {
  65. if (!cmp) cmp = defaultCmp
  66. var i = indexOf(list, value, cmp)
  67. if (i === -1) return -1
  68. return cmp(list[i], value) === 0 ? i : -1
  69. }
  70. function nearest (list, value, cmp) {
  71. if (!cmp) cmp = defaultCmp
  72. var len = list.length
  73. var top = len - 1
  74. var btm = 0
  75. var mid = -1
  76. var trending = 1 // 0 = down, 2 = up
  77. while (top >= btm && btm >= 0 && top < len) {
  78. mid = Math.floor((top + btm) / 2)
  79. var c = cmp(list[mid], value)
  80. if (c === 0) return mid
  81. if (c >= 0) {
  82. if (trending === 1) trending = 0
  83. else if (trending === 2) {
  84. if (Math.abs(list[mid] - value) > Math.abs(list[mid - 1] - value)) return mid - 1
  85. return mid
  86. }
  87. top = mid - 1
  88. } else {
  89. if (trending === 1) trending = 2
  90. else if (trending === 0) return mid
  91. btm = mid + 1
  92. }
  93. }
  94. return mid
  95. }
  96. function indexOf (list, value, cmp) {
  97. if (!cmp) cmp = defaultCmp
  98. var len = list.length
  99. var top = len - 1
  100. var btm = 0
  101. var mid = -1
  102. while (top >= btm && btm >= 0 && top < len) {
  103. mid = Math.floor((top + btm) / 2)
  104. var c = cmp(list[mid], value)
  105. if (c === 0) return mid
  106. if (c >= 0) {
  107. top = mid - 1
  108. } else {
  109. btm = mid + 1
  110. }
  111. }
  112. return mid
  113. }
  114. function has (list, value, cmp) {
  115. return eq(list, value, cmp) > -1
  116. }
  117. function remove (list, value, cmp) {
  118. var i = eq(list, value, cmp)
  119. if (i === -1) return false
  120. list.splice(i, 1)
  121. return true
  122. }