objectUtils.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /**
  2. * @category Services/utils
  3. * @class ObjectUtils
  4. * Classe aidant à manipuler des Objets
  5. */
  6. import type { AnyJson } from '~/types/data'
  7. export default class ObjectUtils {
  8. /**
  9. * Flatten un objet nested en un objet avec un seul niveau avec des noms de propriétés transformées comme cela 'foo.bar'
  10. * L'objet passé en paramètre reste inchangé car il est cloné
  11. *
  12. * @example cloneAndFlatten({ a: 1, b: { c: 2 }, d: { e: 3, f: { g: 4, h: 5 } }, i: { j: 6 } }, ['i']) => { a: 1, 'b.c': 2, 'd.e': 3, 'd.f.g': 4, 'd.f.h': 5, i: { j: 6 } } }
  13. * @param {AnyJson} object
  14. * @param {Array<string>} excludedProperties
  15. * @param excludedProperties
  16. * @return {AnyJson}
  17. */
  18. static cloneAndFlatten(
  19. object: AnyJson,
  20. excludedProperties: Array<string> = [],
  21. ): AnyJson {
  22. if (typeof object !== 'object') {
  23. throw new TypeError('Expecting an object parameter')
  24. }
  25. return Object.keys(object).reduce((values: AnyJson, name: string) => {
  26. if (!Object.prototype.hasOwnProperty.call(object, name)) {
  27. return values
  28. }
  29. if (this.isObject(object[name])) {
  30. if (!excludedProperties.includes(name)) {
  31. const flatObject = this.cloneAndFlatten(object[name])
  32. Object.keys(flatObject).forEach((flatObjectKey) => {
  33. if (
  34. !Object.prototype.hasOwnProperty.call(flatObject, flatObjectKey)
  35. ) {
  36. return
  37. }
  38. values[name + '.' + flatObjectKey] = flatObject[flatObjectKey]
  39. })
  40. } else {
  41. values[name] = this.clone(object[name])
  42. }
  43. } else {
  44. values[name] = object[name]
  45. }
  46. return values
  47. }, {})
  48. }
  49. /**
  50. * Transforme un objet flattened en un objet nested. L'objet passé en paramètre reste inchangé
  51. *
  52. * @example cloneAndNest({ a: 1, 'b.c': 2, 'd.e': 3, 'd.f.g': 4, 'd.f.h': 5 } ) => { a: 1, b: { c: 2 }, d: { e: 3, f: { g: 4, h: 5 } } }
  53. * @param {AnyJson} object
  54. * @return {AnyJson}
  55. */
  56. static cloneAndNest(object: AnyJson): AnyJson {
  57. if (typeof object !== 'object') {
  58. throw new TypeError('Expecting an object parameter')
  59. }
  60. return Object.keys(object).reduce((values, name) => {
  61. if (!Object.prototype.hasOwnProperty.call(object, name)) {
  62. return values
  63. }
  64. name
  65. .split('.')
  66. .reduce(
  67. (
  68. previous: AnyJson,
  69. current: string,
  70. index: number,
  71. list: Array<string>,
  72. ) => {
  73. if (previous != null) {
  74. if (typeof previous[current] === 'undefined') {
  75. previous[current] = {}
  76. }
  77. if (index < list.length - 1) {
  78. return previous[current]
  79. }
  80. previous[current] = object[name]
  81. }
  82. return null
  83. },
  84. values,
  85. )
  86. return values
  87. }, {})
  88. }
  89. /**
  90. * Teste si le paramètre est un objet
  91. *
  92. * @param {AnyJson} value
  93. * @return {boolean}
  94. */
  95. static isObject(value: unknown): boolean {
  96. return (
  97. value !== null &&
  98. typeof value === 'object' &&
  99. !Array.isArray(value) &&
  100. ObjectUtils.prototype.toString.call(value) !== '[object Date]'
  101. )
  102. }
  103. /**
  104. * Clone l'objet et ses propriétés.
  105. *
  106. * @param {ObjectUtils} object
  107. * @return {ObjectUtils}
  108. */
  109. static clone(object: AnyJson): AnyJson {
  110. return Object.keys(object).reduce((values: AnyJson, name: string) => {
  111. if (Object.prototype.hasOwnProperty.call(object, name)) {
  112. values[name] = object[name]
  113. }
  114. return values
  115. }, {})
  116. }
  117. /**
  118. * Trie un objet selon ses clés (par ordre alphanumérique)
  119. *
  120. * @example sortObjectsByKey({b:1, d:2, c:3, a:4}) => {a:4, b:1, c:3, d:2}
  121. * @param toSort
  122. */
  123. static sortObjectsByKey(toSort: AnyJson): AnyJson {
  124. if (typeof toSort !== 'object') {
  125. throw new TypeError('Expecting an object parameter')
  126. }
  127. return Object.keys(toSort)
  128. .sort()
  129. .reduce((obj: AnyJson, key: string) => {
  130. obj[key] = toSort[key]
  131. return obj
  132. }, {})
  133. }
  134. }