Last active
August 28, 2016 10:43
-
-
Save keyserfaty/0798b4177c9eb54864fb1d38a18f36b4 to your computer and use it in GitHub Desktop.
Extract different props from comparing two objects
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const obj1 = { | |
| url: ['1', '2', '3'], | |
| fonts: { | |
| first: [1, 2], | |
| second: '2' | |
| }, | |
| border: [1, 2, 3] | |
| }; | |
| const obj2 = { | |
| url: ['1', '3', '4', '7'], | |
| fonts: { | |
| first: [5, 7, 2], | |
| second: '2' | |
| }, | |
| border: [1, 2, 4, 6] | |
| }; | |
| /** | |
| * Type checkers | |
| */ | |
| const isObject = col => !Array.isArray(col) && typeof col === 'object'; | |
| const isArray = col => Array.isArray(col); | |
| const obj = isObject; | |
| const arr = isArray; | |
| /* | |
| * Iterators for objects/arrays | |
| */ | |
| const map = (col, fn) => ( | |
| (obj(col) ? Object.keys(col) : col).map((key, i) => ( | |
| fn( | |
| (obj(col) ? col[key] : key), | |
| (obj(col) ? key : i), | |
| col | |
| ) | |
| )) | |
| ); | |
| const filter = (col, fn) => { | |
| let res = []; | |
| (obj(col) ? Object.keys(col) : col).forEach((key, i) => ( | |
| fn(key, i, col) && ( | |
| res.push(obj(col) ? col[key] : key) | |
| ) | |
| )) | |
| return res; | |
| }; | |
| let res = {}; | |
| let parent = ''; | |
| const extractDiffProps = (previous, updated) => { | |
| map(previous, (elem, key) => { | |
| if (obj(elem)) { | |
| // Preserve the parent's key to create the returned object later | |
| parent = key; | |
| // If it finds an object call the fn again | |
| return extractDiffProps(elem, updated[key]); | |
| } | |
| // Clean the parent's name if no longer in that object | |
| if (updated[parent] !== previous[parent]) parent = ''; | |
| if (arr(elem)) { | |
| // If array is inside an object: preserve parent's name as the key | |
| !!parent && (res[parent] = { | |
| [key]: updated[key].filter(i => !elem.includes(i)) | |
| }); | |
| // If array is not inside an object: key is equal to the currents element key | |
| !parent && (res[key] = updated[key].filter(i => !elem.includes(i))); | |
| return; | |
| } | |
| if (elem !== updated[key]) { | |
| // If object already exists: update it with a new prop | |
| res[parent] && (res[parent][key] = updated[key]); | |
| // If object doesn't exists: crete a new one | |
| !res[parent] && (res[parent] = { | |
| [key]: updated[key] | |
| }) | |
| } | |
| }); | |
| return res; | |
| }; | |
| const res2 = extractDiffProps(obj1, obj2) | |
| console.log(JSON.stringify(res2, null, 2)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment