Last active
December 7, 2021 13:01
-
-
Save Seterium/53d16b04ef2c6984b73d07d9162e47da to your computer and use it in GitHub Desktop.
Objects diff
This file contains 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 arraysDiff = (origin, base) => origin.filter(x => !base.includes(x)); | |
// Определение пустого объекта (без свойств) | |
const isEmpty = (object) => { | |
if (!(object instanceof Object)) { | |
throw new TypeError('isEmpty argument must be an Object type'); | |
} | |
return !Object.keys(object); | |
}; | |
// Вычисление отличий объекта A от объекта B | |
// Важные моменты | |
// - Строго проверяется тип примитивов, а также null, NaN и undefined | |
// - Порядок свойств в объекте не учитывается | |
// - Порядок элементов во вложенных масссивах не учитывается | |
// - Повторения элементов во вложенных массивах не учитываются (предполагается, что каждое значение уникальное) | |
// - Порядок отличающихся свойств соответствует порядку свойств в объекте A | |
const objectsDiff = (objectA, objectB) => { | |
const diff = (origin, base) => { | |
const diffs = {}; | |
for (const key in origin) { | |
const originType = typeof origin[key]; | |
const baseType = typeof base[key]; | |
if (originType === baseType) { | |
if (Array.isArray(origin[key])) { | |
const arrayDiffs = arraysDiff(origin[key], base[key]); | |
if (arrayDiffs.length) { | |
diffs[key] = arrayDiffs; | |
} | |
} else if (originType === 'object' && origin[key] !== null && origin[key] !== undefined) { | |
const objectsDiff = diff(origin[key], base[key]); | |
if (!isEmpty(objectsDiff)) { | |
diffs[key] = objectsDiff; | |
} | |
} else if (origin[key] !== base[key]) { | |
diffs[key] = origin[key]; | |
} | |
} else { | |
diffs[key] = origin[key]; | |
} | |
} | |
return diffs; | |
}; | |
return diff(objectA, objectB); | |
}; | |
const objA = { | |
a: 1, | |
b: true, | |
c: [5, 2, 1], | |
d: { | |
d1: 2, | |
d2: 4, | |
d3: 6 | |
} | |
} | |
const objB = { | |
a: 2, | |
b: false, | |
c: [1, 2, 3], | |
d: { | |
d1: 1, | |
d2: 4, | |
d3: 5 | |
} | |
} | |
console.log(objectsDiff(objA, objB)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment