algorithmUtil.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /**
  2. * Get index with specific start index one by one. e.g.
  3. * min: 3, max: 9, start: 6
  4. *
  5. * Return index is:
  6. * [0]: 6
  7. * [1]: 7
  8. * [2]: 5
  9. * [3]: 8
  10. * [4]: 4
  11. * [5]: 9
  12. * [6]: 3
  13. */
  14. export function getIndexByStartLoc(min, max, start, index) {
  15. const beforeCount = start - min;
  16. const afterCount = max - start;
  17. const balanceCount = Math.min(beforeCount, afterCount) * 2;
  18. // Balance
  19. if (index <= balanceCount) {
  20. const stepIndex = Math.floor(index / 2);
  21. if (index % 2) {
  22. return start + stepIndex + 1;
  23. }
  24. return start - stepIndex;
  25. }
  26. // One is out of range
  27. if (beforeCount > afterCount) {
  28. return start - (index - afterCount);
  29. }
  30. return start + (index - beforeCount);
  31. }
  32. /**
  33. * We assume that 2 list has only 1 item diff and others keeping the order.
  34. * So we can use dichotomy algorithm to find changed one.
  35. */
  36. export function findListDiffIndex(originList, targetList, getKey) {
  37. const originLen = originList.length;
  38. const targetLen = targetList.length;
  39. let shortList;
  40. let longList;
  41. if (originLen === 0 && targetLen === 0) {
  42. return null;
  43. }
  44. if (originLen < targetLen) {
  45. shortList = originList;
  46. longList = targetList;
  47. } else {
  48. shortList = targetList;
  49. longList = originList;
  50. }
  51. const notExistKey = {
  52. __EMPTY_ITEM__: true
  53. };
  54. function getItemKey(item) {
  55. if (item !== undefined) {
  56. return getKey(item);
  57. }
  58. return notExistKey;
  59. }
  60. // Loop to find diff one
  61. let diffIndex = null;
  62. let multiple = Math.abs(originLen - targetLen) !== 1;
  63. for (let i = 0; i < longList.length; i += 1) {
  64. const shortKey = getItemKey(shortList[i]);
  65. const longKey = getItemKey(longList[i]);
  66. if (shortKey !== longKey) {
  67. diffIndex = i;
  68. multiple = multiple || shortKey !== getItemKey(longList[i + 1]);
  69. break;
  70. }
  71. }
  72. return diffIndex === null ? null : {
  73. index: diffIndex,
  74. multiple
  75. };
  76. }