arrayMapper.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import { arrayEach, arrayReduce, arrayMap, arrayMax } from './../helpers/array';
  2. import { defineGetter } from './../helpers/object';
  3. import { rangeEach } from './../helpers/number';
  4. var MIXIN_NAME = 'arrayMapper';
  5. /**
  6. * @type {Object}
  7. */
  8. var arrayMapper = {
  9. _arrayMap: [],
  10. /**
  11. * Get value by map index.
  12. *
  13. * @param {Number} index Array index.
  14. * @return {*} Returns value mapped to passed index.
  15. */
  16. getValueByIndex: function getValueByIndex(index) {
  17. var value = void 0;
  18. /* eslint-disable no-cond-assign */
  19. return (value = this._arrayMap[index]) === void 0 ? null : value;
  20. },
  21. /**
  22. * Get map index by its value.
  23. *
  24. * @param {*} value Value to search.
  25. * @returns {Number} Returns array index.
  26. */
  27. getIndexByValue: function getIndexByValue(value) {
  28. var index = void 0;
  29. /* eslint-disable no-cond-assign */
  30. return (index = this._arrayMap.indexOf(value)) === -1 ? null : index;
  31. },
  32. /**
  33. * Insert new items to array mapper starting at passed index. New entries will be a continuation of last value in the array.
  34. *
  35. * @param {Number} index Array index.
  36. * @param {Number} [amount=1] Defines how many items will be created to an array.
  37. * @returns {Array} Returns added items.
  38. */
  39. insertItems: function insertItems(index) {
  40. var _this = this;
  41. var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
  42. var newIndex = arrayMax(this._arrayMap) + 1;
  43. var addedItems = [];
  44. rangeEach(amount - 1, function (count) {
  45. addedItems.push(_this._arrayMap.splice(index + count, 0, newIndex + count));
  46. });
  47. return addedItems;
  48. },
  49. /**
  50. * Remove items from array mapper.
  51. *
  52. * @param {Number} index Array index.
  53. * @param {Number} [amount=1] Defines how many items will be created to an array.
  54. * @returns {Array} Returns removed items.
  55. */
  56. removeItems: function removeItems(index) {
  57. var _this2 = this;
  58. var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
  59. var removedItems = [];
  60. if (Array.isArray(index)) {
  61. var mapCopy = [].concat(this._arrayMap);
  62. // Sort descending
  63. index.sort(function (a, b) {
  64. return b - a;
  65. });
  66. removedItems = arrayReduce(index, function (acc, item) {
  67. _this2._arrayMap.splice(item, 1);
  68. return acc.concat(mapCopy.slice(item, item + 1));
  69. }, []);
  70. } else {
  71. removedItems = this._arrayMap.splice(index, amount);
  72. }
  73. return removedItems;
  74. },
  75. /**
  76. * Unshift items (remove and shift chunk of array to the left).
  77. *
  78. * @param {Number|Array} index Array index or Array of indexes to unshift.
  79. * @param {Number} [amount=1] Defines how many items will be removed from an array (when index is passed as number).
  80. */
  81. unshiftItems: function unshiftItems(index) {
  82. var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
  83. var removedItems = this.removeItems(index, amount);
  84. function countRowShift(logicalRow) {
  85. // Todo: compare perf between reduce vs sort->each->brake
  86. return arrayReduce(removedItems, function (count, removedLogicalRow) {
  87. if (logicalRow > removedLogicalRow) {
  88. count++;
  89. }
  90. return count;
  91. }, 0);
  92. }
  93. this._arrayMap = arrayMap(this._arrayMap, function (logicalRow, physicalRow) {
  94. var rowShift = countRowShift(logicalRow);
  95. if (rowShift) {
  96. logicalRow -= rowShift;
  97. }
  98. return logicalRow;
  99. });
  100. },
  101. /**
  102. * Shift (right shifting) items starting at passed index.
  103. *
  104. * @param {Number} index Array index.
  105. * @param {Number} [amount=1] Defines how many items will be created to an array.
  106. */
  107. shiftItems: function shiftItems(index) {
  108. var _this3 = this;
  109. var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
  110. this._arrayMap = arrayMap(this._arrayMap, function (row) {
  111. if (row >= index) {
  112. row += amount;
  113. }
  114. return row;
  115. });
  116. rangeEach(amount - 1, function (count) {
  117. _this3._arrayMap.splice(index + count, 0, index + count);
  118. });
  119. },
  120. /**
  121. * Clear all stored index<->value information from an array.
  122. */
  123. clearMap: function clearMap() {
  124. this._arrayMap.length = 0;
  125. }
  126. };
  127. defineGetter(arrayMapper, 'MIXIN_NAME', MIXIN_NAME, {
  128. writable: false,
  129. enumerable: false
  130. });
  131. export default arrayMapper;