Advertisement
k98kurz

diff.js

Feb 27th, 2021 (edited)
377
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* Helper functions that can be used in componentDidUpdate to find what changed between component updates.
  2.   Example: componentDidUpdate(prevProps, prevState) {
  3.     const propsChanged = changes(prevProps, this.props);
  4.     const stateChanged = changes(prevState, this.state);
  5.     const propsDiff = diff(prevProps, this.props);
  6.     const stateDiff = diff(prevState, this.state);
  7.  
  8.     if (propsChanged.someDataThing) {
  9.       this.doStuff(propsDiff.someDataThing);
  10.     }
  11.  
  12.     if (stateChanged.intermediateValue) {
  13.       this.continueThing();
  14.     }
  15.   }
  16. */
  17.  
  18. // Copyright (c) 2021 Jonathan Voss
  19. // BSD0 license
  20. // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
  21. // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
  22. // TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
  23. // NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  24. // DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
  25. // IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  26. // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  
  28. // compares two objects and returns recursive boolean flags for what properties are different
  29. // flags will not appear for any non-array without a difference in content
  30. // flag will be false for two equivalent arrays that are different instances
  31. export function changes (obj1, obj2) {
  32.   let flags = {};
  33.  
  34.   Object.keys(obj2).forEach(k => {
  35.     if ((!obj1[k] && !!obj2[k]) || obj1[k] !== obj2[k]) {
  36.       if (typeof obj1[k] == 'undefined' || typeof obj2[k] == 'undefined' || obj1[k] == null || obj2[k] == null || obj1[k].constructor.name !== obj2[k].constructor.name) {
  37.         flags[k] = true;
  38.       } else {
  39.         switch (obj1[k].constructor.name) {
  40.           case 'Array':
  41.             flags[k] = (obj2[k].constructor.name == 'Array') ? obj1[k].filter(x => !obj2[k].includes(x)).length > 0 : true;
  42.             break;
  43.           case 'Object':
  44.             flags[k] = changes(obj1[k], obj2[k]);
  45.             break;
  46.           default:
  47.             flags[k] = true;
  48.         }
  49.       }
  50.     }
  51.   });
  52.  
  53.   Object.keys(obj1).forEach(k => {
  54.     if ((!!obj1[k] && !obj2[k]) || obj1[k] !== obj2[k]) {
  55.       if (typeof obj1[k] == 'undefined' || typeof obj2[k] == 'undefined' || obj1[k] == null || obj2[k] == null || obj1[k].constructor.name !== obj2[k].constructor.name) {
  56.         flags[k] = true;
  57.       } else {
  58.         switch (obj2[k].constructor.name) {
  59.           case 'Array':
  60.             flags[k] = (obj1[k].constructor.name == 'Array') ? obj2[k].filter(x => !obj1[k].includes(x)).length > 0 : true;
  61.             break;
  62.           case 'Object':
  63.             flags[k] = changes(obj1[k], obj2[k]);
  64.             if (flags[k].constructor.name == 'Object' && Object.keys(flags[k]).length < 1) {
  65.               delete flags[k];
  66.             }
  67.             break;
  68.           default:
  69.             flags[k] = true;
  70.         }
  71.       }
  72.     }
  73.   });
  74.  
  75.   return flags;
  76. }
  77.  
  78. // compares two objects and returns whatever properties were overwritten by obj2
  79. export function diff (obj1, obj2) {
  80.   let flags = changes(obj1, obj2);
  81.   let difference = {};
  82.   Object.keys(flags).forEach(k => {
  83.     if (typeof obj1[k] == 'undefined' || typeof obj2[k] == 'undefined' || obj1[k] == null || obj2[k] == null || obj1[k].constructor.name !== obj2[k].constructor.name) {
  84.       difference[k] = obj2[k];
  85.       return;
  86.     }
  87.  
  88.     switch (obj1[k].constructor.name) {
  89.       case 'Array':
  90.         if (obj2[k].constructor.name)
  91.           difference[k] = obj2[k].filter(x => !obj1[k].includes(k));
  92.         else
  93.           difference[k] = obj2[k];
  94.         break;
  95.       case 'Object':
  96.         difference[k] = diff(obj1[k], obj2[k]);
  97.         if (Object.keys(difference[k]).length < 1) {
  98.           delete difference[k];
  99.         }
  100.         break;
  101.       case 'Number':
  102.       case 'Boolean':
  103.       case 'Boolean':
  104.       case 'String':
  105.       default:
  106.         difference[k] = obj2[k];
  107.     }
  108.   });
  109.  
  110.   return difference;
  111. }
  112.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement