index.js 3.1 KB

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