1
0

index.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. export function toSetMethodName(key: string) {
  2. return 'set' + key[0].toUpperCase() + key.slice(1)
  3. }
  4. export const merge = (target: any, source: any) => {
  5. // Iterate through `source` properties and if an `Object` set property to merge of `target` and `source` properties
  6. for (const key of Object.keys(source)) {
  7. if (source[key] instanceof Object) Object.assign(source[key], merge(target[key], source[key]))
  8. }
  9. // Join `target` and modified `source`
  10. Object.assign(target || {}, source)
  11. return target
  12. }
  13. const HTML_TAGS =
  14. 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' +
  15. 'header,hgroup,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,' +
  16. 'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' +
  17. 'data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,' +
  18. 'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' +
  19. 'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' +
  20. 'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' +
  21. 'option,output,progress,select,textarea,details,dialog,menu,' +
  22. 'summary,template,blockquote,iframe,tfoot'
  23. export const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS)
  24. export function kebabToCamel(str: string) {
  25. return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase())
  26. }
  27. export function makeMap(str: string, expectsLowerCase?: boolean): (key: string) => boolean {
  28. const map: Record<string, boolean> = Object.create(null)
  29. const list: Array<string> = str.split(',')
  30. for (let i = 0; i < list.length; i++) {
  31. map[list[i]] = true
  32. }
  33. return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val]
  34. }
  35. export const uniqueBy = <T, K>(array: T[], iteratee: (value: T) => K): T[] => {
  36. const seen = new Set<K>()
  37. const result: T[] = []
  38. for (const item of array) {
  39. const identifier = iteratee(item)
  40. if (!seen.has(identifier)) {
  41. seen.add(identifier)
  42. result.push(item)
  43. }
  44. }
  45. return result
  46. }
  47. export const get = <T>(obj: any, path: string | string[]): T | undefined => {
  48. if (!path) return undefined;
  49. // Regex explained: https://regexr.com/58j0k
  50. const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g);
  51. return pathArray?.reduce((prevObj, key) => prevObj && prevObj[key], obj);
  52. };
  53. export const set = (obj: any, path: string | string[], value: any): void => {
  54. // Regex explained: https://regexr.com/58j0k
  55. const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g);
  56. if (pathArray)
  57. pathArray.reduce((acc, key, i) => {
  58. if (acc[key] === undefined) acc[key] = {};
  59. if (i === pathArray.length - 1) acc[key] = value;
  60. return acc[key];
  61. }, obj);
  62. };
  63. export function deepEqual(a: any, b: any): boolean {
  64. // If both are primitives, return true if they are equal
  65. if (a === b) return true;
  66. // If either of them is null or not an object, return false
  67. if (a === null || typeof a !== "object" || b === null || typeof b !== "object") return false;
  68. // Get the keys of both objects
  69. const keysA = Object.keys(a), keysB = Object.keys(b);
  70. // If they have different number of keys, they are not equal
  71. if (keysA.length !== keysB.length) return false;
  72. // Check each key in A to see if it exists in B and its value is the same in both
  73. for (const key of keysA) {
  74. if (!keysB.includes(key) || !deepEqual(a[key], b[key])) return false;
  75. }
  76. return true;
  77. }
  78. export function deepArrayEqual(arr1: any[], arr2: any[]): boolean {
  79. // If they're not both arrays, return false
  80. if (!Array.isArray(arr1) || !Array.isArray(arr2)) return false;
  81. // If they don't have the same length, they're not equal
  82. if (arr1.length !== arr2.length) return false;
  83. // Check each element of arr1 against the corresponding element of arr2
  84. for (let i = 0; i < arr1.length; i++) {
  85. if (!deepEqual(arr1[i], arr2[i])) return false;
  86. }
  87. return true;
  88. }