d3a1264d75e75d6f05e1756335c2e9eb545f1c92286adbf4306cccceedd93ef0dd907d89880b5e8a85716b1f62c7505807aace72e26999bccccc4998f37056 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. function MultiMap() {
  2. var map = {
  3. arrayMap: [],
  4. weakMap: new WeakMap(),
  5. };
  6. return {
  7. get(key) {
  8. if (canBeAnArrayMapKey(key)) {
  9. return map.arrayMap[key];
  10. } else if (canBeAWeakMapKey(key)) {
  11. return map.weakMap.get(key);
  12. }
  13. },
  14. set(key, value) {
  15. if (canBeAnArrayMapKey(key)) {
  16. map.arrayMap[key] = value;
  17. } else if (canBeAWeakMapKey(key)) {
  18. map.weakMap.set(key, value);
  19. } else {
  20. throw new Error('Invalid key type');
  21. }
  22. },
  23. delete(key) {
  24. if (canBeAnArrayMapKey(key)) {
  25. delete map.arrayMap[key];
  26. } else if (canBeAWeakMapKey(key)) {
  27. map.weakMap.delete(key);
  28. }
  29. },
  30. };
  31. function canBeAnArrayMapKey(obj) {
  32. return obj !== null && !isNaNSymbol(obj) && (typeof obj == 'string' || typeof obj == 'number');
  33. }
  34. function canBeAWeakMapKey(obj) {
  35. return obj !== null && (typeof obj == 'object' || typeof obj == 'function');
  36. }
  37. function isNaNSymbol(obj) {
  38. /* eslint-disable no-self-compare */
  39. return obj !== obj; // NaN === NaN is always false
  40. }
  41. }
  42. export default MultiMap;