У меня есть 2 вложенных объекта, которые отличаются друг от друга, и мне нужно знать, имеют ли они различия в одном из своих вложенных свойств.
var a = {};
var b = {};
a.prop1 = 2;
a.prop2 = { prop3: 2 };
b.prop1 = 2;
b.prop2 = { prop3: 3 };
Объект может быть намного сложнее с более вложенными свойствами. Но это хороший пример. У меня есть возможность использовать рекурсивные функции или что-то с lodash ...
javascript
lodash
JLavoie
источник
источник
_.isEqual(value, other)
Выполняет глубокое сравнение между двумя значениями, чтобы определить, являются ли они эквивалентными. lodash.com/docs#isEqualОтветы:
Простым и элегантным решением является использование
_.isEqual
, которое выполняет глубокое сравнение:Однако это решение не показывает, какое свойство отличается.
http://jsfiddle.net/bdkeyn0h/
источник
_.isEqual
может быть довольно сложно. Если вы скопируете объект и измените там некоторые значения, он все равно будет показывать true, потому что ссылка такая же. Поэтому следует быть осторожным, используя эту функцию.Если вам нужно узнать, какие свойства различаются, используйте redu () :
источник
_.reduce(a, (result, value, key) => _.isEqual(value, b[key]) ? result : result.concat(key), [])
для однострочного решенияlet edited = _.reduce(a, function(result, value, key) { return _.isEqual(value, b[key]) ? result : result.concat( { [key]: value } ); }, []);
Для тех, кто наткнулся на эту тему, вот более полное решение. Он будет сравнивать два объекта и даст вам ключ всех свойств, которые либо только в object1 , только в object2 , либо оба в object1 и object2, но имеют разные значения :
Вот пример вывода:
Если вы не заботитесь о вложенных объектах и хотите пропустить lodash, вы можете заменить
_.isEqual
обычное сравнение значений, напримерobj1[key] === obj2[key]
.источник
Основываясь на ответе Адама Бодуха , я написал эту функцию, которая сравнивает два объекта в самом глубоком смысле , возвращая пути, которые имеют разные значения, а также пути, отсутствующие в одном или другом объекте.
Код не был написан с учетом эффективности, и улучшения в этом отношении приветствуются, но вот основная форма:
Вы можете попробовать код, используя этот фрагмент (рекомендуется запуск в режиме полной страницы):
Показать фрагмент кода
источник
b
с помощьюb.hasOwnProperty(key)
илиkey in b
, а не сb[key] != undefined
. При использовании старой версииb[key] != undefined
функция возвращала неверный diff для объектов, содержащихundefined
, как вcompare({disabled: undefined}, {disabled: undefined})
. На самом деле, старая версия также имела проблемы сnull
; Вы можете избежать подобных проблем, всегда используя===
и!==
вместо==
и!=
.Вот краткое решение:
источник
[]
.Чтобы рекурсивно показать, как объект отличается от другого, вы можете использовать _.reduce в сочетании с _.isEqual и _.isPlainObject . В этом случае вы можете сравнить разницу a с b или b с a:
источник
Простой
_.isEqual
способ использования , он будет работать для всех сравнений ...Так что если у вас есть ниже:
Если вы делаете:
_.isEqual(firstName, otherName);
,это вернет истину
И если
const fullName = {firstName: "Alireza", familyName: "Dezfoolian"};
Если вы делаете:
_.isEqual(firstName, fullName);
,вернет ложь
источник
Этот код возвращает объект со всеми свойствами, которые имеют разные значения, а также значения обоих объектов. Полезно для регистрации разницы.
источник
Без использования lodash / underscore, я написал этот код и отлично работает для меня для глубокого сравнения object1 с object2
источник
Глубокое сравнение с использованием шаблона (вложенных) свойств для проверки
Это будет работать в консоли. Поддержка массива может быть добавлена при необходимости
источник
Я взял код Адама Бодуха, чтобы вывести глубокую разницу - это полностью не проверено, но есть фрагменты:
источник
diff({}, { foo: 'lol', bar: { baz: true }}) // returns []
Как и было задано, вот рекурсивная функция сравнения объектов. И еще немного. Предполагая, что основное использование такой функции - проверка объекта, мне есть что сказать. Полное глубокое сравнение - плохая идея, когда некоторые различия не имеют значения. Например, слепое глубокое сравнение в утверждениях TDD делает тесты ненужными хрупкими. По этой причине я хотел бы представить гораздо более ценный частичный diff . Это рекурсивный аналог предыдущего вклада в эту тему. Он игнорирует ключи , отсутствующие в а
BDiff позволяет проверять ожидаемые значения, допуская другие свойства, что именно то, что вы хотите для автоматической проверки. Это позволяет строить все виды расширенных утверждений. Например:
Возвращаясь к полному решению. Создать полный традиционный diff с помощью bdiff тривиально:
Запуск вышеуказанной функции на двух сложных объектах выведет что-то похожее на это:
Наконец, для того, чтобы получить представление о различии значений, мы можем напрямую вычислить () вывод diff. Для этого нам нужна более уродливая версия bdiff, которая выводит синтаксически правильные пути:
Это выведет что-то похожее на это:
Лицензия MIT;)
источник
Завершая ответ Адама Бодуха, он учитывает различия в свойствах
источник
Если вам нужно только сравнение ключей:
источник
Вот простой Typescript с Lodash для проверки глубинных различий, который создаст новый объект с теми же различиями, что и между старым и новым объектами.
Например, если бы мы имели:
результирующий объект будет:
Он также совместим с многоуровневыми глубокими объектами, для массивов может потребоваться некоторая настройка.
источник
источник
===
напрямую,{ a: 20 } === { a: 20 }
вернет false, потому что он сравнивает прототип. Более правильный способ в первую очередь сравнить объекты, чтобы обернуть их вJSON.stringify()
_.isEqual(f, s)
? :)f
это объект, и вы попадаете к немуif (_.isObject(f))
, просто вернитесь через функцию и снова нажмите эту точку. То же самое касаетсяf (Array.isArray(f)&&Array.isArray(s))
это было основано на @JLavoie , используя lodash
https://jsfiddle.net/EmilianoBarboza/0g0sn3b9/8/
источник
просто с помощью Vanilla JS
источник
Чтобы развить ответ Шридхара Гудимелы , здесь он обновляется таким образом, чтобы сделать Flow счастливым:
источник