Skip to content

Instantly share code, notes, and snippets.

@Seterium
Last active December 7, 2021 13:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Seterium/53d16b04ef2c6984b73d07d9162e47da to your computer and use it in GitHub Desktop.
Save Seterium/53d16b04ef2c6984b73d07d9162e47da to your computer and use it in GitHub Desktop.
Objects diff
// Вычисление расхождения массивов
// Важно:
// - Порядок элементов не учитывается
// - Повторение элементов не учитывается
// - Вложенные типы должны быть примитивными значениями (строками, числами, булевыми значениями)
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