index.js 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. module.exports = abbrev
  2. function abbrev (...args) {
  3. let list = args
  4. if (args.length === 1 && (Array.isArray(args[0]) || typeof args[0] === 'string')) {
  5. list = [].concat(args[0])
  6. }
  7. for (let i = 0, l = list.length; i < l; i++) {
  8. list[i] = typeof list[i] === 'string' ? list[i] : String(list[i])
  9. }
  10. // sort them lexicographically, so that they're next to their nearest kin
  11. list = list.sort(lexSort)
  12. // walk through each, seeing how much it has in common with the next and previous
  13. const abbrevs = {}
  14. let prev = ''
  15. for (let ii = 0, ll = list.length; ii < ll; ii++) {
  16. const current = list[ii]
  17. const next = list[ii + 1] || ''
  18. let nextMatches = true
  19. let prevMatches = true
  20. if (current === next) {
  21. continue
  22. }
  23. let j = 0
  24. const cl = current.length
  25. for (; j < cl; j++) {
  26. const curChar = current.charAt(j)
  27. nextMatches = nextMatches && curChar === next.charAt(j)
  28. prevMatches = prevMatches && curChar === prev.charAt(j)
  29. if (!nextMatches && !prevMatches) {
  30. j++
  31. break
  32. }
  33. }
  34. prev = current
  35. if (j === cl) {
  36. abbrevs[current] = current
  37. continue
  38. }
  39. for (let a = current.slice(0, j); j <= cl; j++) {
  40. abbrevs[a] = current
  41. a += current.charAt(j)
  42. }
  43. }
  44. return abbrevs
  45. }
  46. function lexSort (a, b) {
  47. return a === b ? 0 : a > b ? 1 : -1
  48. }