Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Deep diff between two object, using lodash
/**
* Deep diff between two object, using lodash
* @param {Object} object Object compared
* @param {Object} base Object to compare with
* @return {Object} Return a new object who represent the diff
*/
function difference(object, base) {
function changes(object, base) {
return _.transform(object, function(result, value, key) {
if (!_.isEqual(value, base[key])) {
result[key] = (_.isObject(value) && _.isObject(base[key])) ? changes(value, base[key]) : value;
}
});
}
return changes(object, base);
}
@Aidurber

This comment has been minimized.

Copy link

@Aidurber Aidurber commented May 2, 2017

Exactly what I was looking for, thanks for this @Yimiprod.

@Odywan55

This comment has been minimized.

Copy link

@Odywan55 Odywan55 commented Jun 27, 2017

Cool, thank you!

@weisk

This comment has been minimized.

Copy link

@weisk weisk commented Nov 14, 2017

good stuff

@Linux249

This comment has been minimized.

Copy link

@Linux249 Linux249 commented Nov 16, 2017

thanks

@oleg-nazarov

This comment has been minimized.

Copy link

@oleg-nazarov oleg-nazarov commented Nov 29, 2017

best practice for me

@claudioc

This comment has been minimized.

Copy link

@claudioc claudioc commented Dec 7, 2017

Thanks!

@jeongsd

This comment has been minimized.

Copy link

@jeongsd jeongsd commented Dec 11, 2017

Good

@kaanon

This comment has been minimized.

Copy link

@kaanon kaanon commented Dec 18, 2017

This works well. Thank you!

@retyui

This comment has been minimized.

Copy link

@retyui retyui commented Jan 18, 2018

Functional programming (FP) exmaple: 🥇

import { transform, isEqual, isObject } from "lodash/fp";

const _transform = transform.convert({
	cap: false
});

const iteratee = baseObj => (result, value, key) => {
	if (!isEqual(value, baseObj[key])) {
		const valIsObj = isObject(value) && isObject(baseObj[key]);
		result[key] = valIsObj === true ? differenceObject(value, baseObj[key]) : value;
	}
};

export function differenceObject(targetObj, baseObj) {
	return _transform(iteratee(baseObj), null, targetObj);
}
@pivcec

This comment has been minimized.

Copy link

@pivcec pivcec commented Jan 18, 2018

thanks!

@codeofsumit

This comment has been minimized.

Copy link

@codeofsumit codeofsumit commented Jan 21, 2018

sweeeet thanks!

@rspicer

This comment has been minimized.

Copy link

@rspicer rspicer commented Feb 13, 2018

Can't confirm if this works on 4.x, but definitely works on 3.x. Thanks so much man!

@borantula

This comment has been minimized.

Copy link

@borantula borantula commented Feb 13, 2018

both nice examples thanks :D

@nickthakkar

This comment has been minimized.

Copy link

@nickthakkar nickthakkar commented Feb 21, 2018

Awesome @Yimiprod.! This is what i was looking for. Thanks a lot !

@Seetha93

This comment has been minimized.

Copy link

@Seetha93 Seetha93 commented Feb 24, 2018

Awesome! Thanks

@dominiceden

This comment has been minimized.

Copy link

@dominiceden dominiceden commented Mar 9, 2018

Thanks, very helpful!

@Thithi32

This comment has been minimized.

Copy link

@Thithi32 Thithi32 commented Mar 28, 2018

Thanks. I tried to make an underscore version shared here: https://gist.github.com/Thithi32/d0a4fcd85953b475a39ef4709e3e7ef5

@jvanderberg

This comment has been minimized.

Copy link

@jvanderberg jvanderberg commented Apr 22, 2018

Thanks much, this works well.

A bit more concisely, not sure the reason for the nested function, as nothing is closed over.

import { transform, isEqual, isObject } from 'lodash';

/**
 * Deep diff between two object, using lodash
 * @param  {Object} object Object compared
 * @param  {Object} base   Object to compare with
 * @return {Object}        Return a new object who represent the diff
 */
function difference(object, base) {
	return transform(object, (result, value, key) => {
		if (!isEqual(value, base[key])) {
			result[key] = isObject(value) && isObject(base[key]) ? difference(value, base[key]) : value;
		}
	});
}
@isaacw

This comment has been minimized.

Copy link

@isaacw isaacw commented Apr 24, 2018

Lifesaver!!!

@racingrebel

This comment has been minimized.

Copy link

@racingrebel racingrebel commented May 9, 2018

Thank you, very nice and clean!
I agree with you @jvanderberg.

@jorgeperegrina

This comment has been minimized.

Copy link

@jorgeperegrina jorgeperegrina commented May 11, 2018

Googled what I wanted to do, clicked on first result, and the magic happened... Thanks a lot!!!

@vitia

This comment has been minimized.

Copy link

@vitia vitia commented Jun 8, 2018

Diff object from these do not reflect removed fields.

@ioanniswd

This comment has been minimized.

Copy link

@ioanniswd ioanniswd commented Jun 10, 2018

awesome

@devp619

This comment has been minimized.

Copy link

@devp619 devp619 commented Jun 13, 2018

This will not work for arrays located within the object 😞

{
  "l0s": [
    {
      "name": "Level 0 Name1",
      "l1s": [
        {
          "name": "Level 1 Name1",
          "l2s": [
            {
              "name": "Level 2 Name1"
            },
            {
              "name": "Level 2 Name2"
            }
          ]
        },
        {
          "name": "Level 1 Name2",
          "l2s": [
            {
              "name": "Level 2 Name3"
            },
            {
              "name": "Level 2 Name4"
            }
          ]
        }
      ]
    },
    {
      "name": "Level 0 Name2",
      "l1s": [
        {
          "name": "Level 1 Name3",
          "l2s": [
            {
              "name": "Level 2 Name5"
            },
            {
              "name": "Level 2 Name6"
            }
          ]
        },
        {
          "name": "Level 1 Name4",
          "l2s": [
            {
              "name": "Level 2 Name7"
            }
          ]
        }
      ]
    }
  ]
}
@darlandieterich

This comment has been minimized.

Copy link

@darlandieterich darlandieterich commented Jul 12, 2018

easter egg 0/

@denis-shostik

This comment has been minimized.

Copy link

@denis-shostik denis-shostik commented Jul 13, 2018

In my case it doesn't work properly, you can test comparison with this objects

 obj1 = {
    b: 2, 
    c: ['2', '1'], 
    d: { baz: 1, bat: 2 },
    e: 1
}

obj2 = {
    a: 1,
    b: 2,
    c: ['1', '2'],
    d: { baz: 1, bat: 2 }
}

difference(obj1, obj2)

And in result we get this following, that actually is wrong, because arrays have the same values

{
    a: 1
    c: ["1", "2"]
}

It can be fixed if we use for arrays comparing with initial sorting, but the array can be deep in object and I don't know how to apply it in code that above, can be somebody have any propositions about it?

_.isEqual(array1.sort(), array2.sort()); 

I have solution for this case, but it looks ugly https://pastebin.com/AtRLqWUr
Oh, I found better solution, with method isEqualWith, https://pastebin.com/M43T4v0k

@code-hunger

This comment has been minimized.

Copy link

@code-hunger code-hunger commented Jul 16, 2018

@denis-shostik no, it does work properly, [1,2] and [2,1] are two different arrays.

@fourthgenz28

This comment has been minimized.

Copy link

@fourthgenz28 fourthgenz28 commented Aug 28, 2018

Very useful, thank you for sharing!

@BoffoF

This comment has been minimized.

Copy link

@BoffoF BoffoF commented Sep 6, 2018

Found a fix to suppress null values in diffed arrays,
e.g.
base = [1,2,3]
object = [1,2,4,5]

result (intial code): [null, null, 4,5]
result (my code): [4,5]

function difference(object, base) {
   function changes(object, base) {
        let arrayIndexCounter = 0;
        return _.transform(object, function (result, value, key) {
            if (!_.isEqual(value, base[key])) {
                let resultKey = _.isArray(base) ? arrayIndexCounter++ : key;
                result[resultKey] = (_.isObject(value) && _.isObject(base[key])) ? changes(value, base[key]) : value;
                console.log("Result: " + JSON.stringify(result));
            }
        });
    }
    return changes(object, base);
}
@cfator

This comment has been minimized.

Copy link

@cfator cfator commented Sep 11, 2018

What about JSON.stringify(obj1) === JSON.stringify(obj2)?

@stubar

This comment has been minimized.

Copy link

@stubar stubar commented Sep 27, 2018

What about JSON.stringify(obj1) === JSON.stringify(obj2)?

That only tells you if it's different, the original functions will "Return a new object who represent the dif"

@Naveenkariyappa

This comment has been minimized.

Copy link

@Naveenkariyappa Naveenkariyappa commented Oct 10, 2018

Tried to used a function
e.g.
base = [1,2,3]
object = [1,2,4,5]

difference(base,object){
// its says _.transform not defined
}

info i have impported _lodash in my file,
advance appologies , Need help i am new to this

@lelandsmith

This comment has been minimized.

Copy link

@lelandsmith lelandsmith commented Oct 24, 2018

Tried to used a function
e.g.
base = [1,2,3]
object = [1,2,4,5]

difference(base,object){
// its says _.transform not defined
}

info i have impported _lodash in my file,
advance appologies , Need help i am new to this

@Naveenkariyappa I have also been getting the same error, did you figure out how to fix this?

@BinarySpike

This comment has been minimized.

Copy link

@BinarySpike BinarySpike commented Nov 5, 2018

@Naveenkariyappa and @lelandsmith,
If using node:
var _ = require('lodash')

See https://lodash.com/

@hieudang-agilityio

This comment has been minimized.

Copy link

@hieudang-agilityio hieudang-agilityio commented Nov 26, 2018

Thanks

@nosovicki

This comment has been minimized.

Copy link

@nosovicki nosovicki commented Dec 11, 2018

In my case it doesn't work properly, you can test comparison with this objects

It can be fixed if we use for arrays comparing with initial sorting, but the array can be deep in object and I don't know how to apply it in code that above, can be somebody have any propositions about it?

_.isEqual(array1.sort(), array2.sort()); 

No need to complicate the diff function. You need it if you use your array as a set, but there's no way to tell it. Better sort your sets within your objects before comparison.

@xibre

This comment has been minimized.

Copy link

@xibre xibre commented Dec 12, 2018

The original function throws a TypeError if base is null or undefined:

difference({ a: true }, null);      // -> TypeError: Cannot read property 'a' of null
difference({ a: true }, undefined); // -> TypeError: Cannot read property 'a' of undefined

In these cases I'd expect it to return object so I have added a simple check and it works fine for me now:

function difference(object, base) {
  if (!base) return object;
  ...
@nirpeled

This comment has been minimized.

Copy link

@nirpeled nirpeled commented Feb 1, 2019

Pure gold!!

@UltraKenchie

This comment has been minimized.

Copy link

@UltraKenchie UltraKenchie commented Mar 26, 2019

Thanks much, this works well.

A bit more concisely, not sure the reason for the nested function, as nothing is closed over.

import { transform, isEqual, isObject } from 'lodash';

/**
 * Deep diff between two object, using lodash
 * @param  {Object} object Object compared
 * @param  {Object} base   Object to compare with
 * @return {Object}        Return a new object who represent the diff
 */
function difference(object, base) {
	return transform(object, (result, value, key) => {
		if (!isEqual(value, base[key])) {
			result[key] = isObject(value) && isObject(base[key]) ? difference(value, base[key]) : value;
		}
	});
}

Loved this. But anyone experienced this code leaving an empty object property?

let source = {
 name: 'test',
 add: 'no'
 link: {
  a: 'fb',
  b: 'twt'
 }
}

let next = {
 name: 'change,
 link: {
  a: 'fb',
  b: 'twt'
 }
}

difference(next, source);

this results in

{
 name: 'change',
 link: {}
}

Is that normal?
I've fixed it by deleting the property if is empty

result[key] = isObject(value) && isObject(base[key]) ? this.difference(value, base[key]) : value;
if (isObject(result[key]) && isEmpty(result[key])) {
     delete result[key];
} else if (isEmpty(result[key])) {
     result[key] = null;
}
@ngothanhtai

This comment has been minimized.

Copy link

@ngothanhtai ngothanhtai commented Apr 14, 2019

really helpful, it helps me to check the different between props and nextProps in React app. Thank you!

@Turbiani

This comment has been minimized.

Copy link

@Turbiani Turbiani commented May 2, 2019

@Yimiprod thanks for that. Is really helpful! In my case, the object base come from MongoDB, so I had add some changes at your original code. If somebody has same case, this is my code.

const _ = require('lodash');
const mongoose = require('mongoose');

function isObjectId(data) {
  if (mongoose.Types.ObjectId.isValid(data) && typeof data === 'object') {
    if (Object.prototype.hasOwnProperty.call(data, 'id') && (typeof data.id === 'object')) {
      return true;
    }
  }
  return false;
}

function customizer(objValue, othValue) {
  if (isObjectId(objValue) && isObjectId(othValue)) {
    return objValue.id.toString('hex') === othValue.id.toString('hex');
  }
  if (isObjectId(objValue) && !isObjectId(othValue)) {
    return objValue.id.toString('hex') === othValue;
  }
  if (!isObjectId(objValue) && isObjectId(othValue)) {
    return objValue === othValue.id.toString('hex');
  }
  return undefined;
}

function difference(object, base) {
  // eslint-disable-next-line no-shadow
  function changes(object, base) {
    return _.transform(object, (result, value, key) => {
      if (!_.isEqualWith(value, base[key], customizer)) {
        result[key]
          = (_.isObject(value) && _.isObject(base[key])) ? changes(value, base[key]) : value;
      }
    });
  }
  return changes(object, base);
}
@NicolasLetellier

This comment has been minimized.

Copy link

@NicolasLetellier NicolasLetellier commented May 30, 2019

This work well when the difference is an added property to the object compared to the base, but not when a property is removed from that base:
As the iteratee function of _.transform is based on the object keys, it can't retrieve keys of the base that have been removed in between.

@UltraKenchie , that's may be why you get an empty object, in my case it was when the object is different from the base, but only by a removed property (in this case, the returned result object from the iteratee stay empty). When a property is removed along other properties' changes, the removal is not identified neither.

Just for you to be sure for what you want to use it.

@dannymartinm

This comment has been minimized.

Copy link

@dannymartinm dannymartinm commented Jun 11, 2019

Works like charm! Thanks for sharing.

@Yimiprod

This comment has been minimized.

Copy link
Owner Author

@Yimiprod Yimiprod commented Jun 12, 2019

Woah i didn't know that gist was still here, thanks everyone for your comments.
I really like the version @jvanderberg proposed.
The FP version from @retyui is really nice too.

@AterDeus

This comment has been minimized.

Copy link

@AterDeus AterDeus commented Oct 9, 2019

@NicolasLetellier Can you help with code, which shows when property is removed?

@NicolasLetellier

This comment has been minimized.

Copy link

@NicolasLetellier NicolasLetellier commented Oct 17, 2019

@AterDeus, that's how I modified Yimiprod's solution to my own needs (being able to spot changed values, but also to spot added and removed properties):

function objectDiff(object, base) {
  function changes(object, base) {
    const accumulator = {};
    Object.keys(base).forEach((key) => {
      if (object[key] === undefined) {
        accumulator[`-${key}`] = base[key];
      }
    });
    return _.transform(
      object,
      (accumulator, value, key) => {
        if (base[key] === undefined) {
          accumulator[`+${key}`] = value;
        } else if (!_.isEqual(value, base[key])) {
          accumulator[key] = (_.isObject(value) && _.isObject(base[key])) ? changes(value, base[key]) : value;
        }
      },
      accumulator
    );
  }
  return changes(object, base);
}

As the _.transform method is iterating only over object (and thus unable to spot removed properties), here I use another loop to iterate before over keys of base. I had to use the accumulator object (check _.transform docs) to conserve the recursive mechanism.
Be aware that this version is adding a + at the beginning of the key of an added property, and a - for removed properties, useful in my use case.

@nicothed

This comment has been minimized.

Copy link

@nicothed nicothed commented Dec 5, 2019

Somehow it doesn't work for dates, so here is a modified version. I also allow to NOT include properties that are set but empty.

isNullBlankOrUndefined = function (o) {
    return (typeof o === "undefined" || o == null || o === "");
}

/**
 * Deep diff between two object, using lodash
 * @param  {Object} object Object compared
 * @param  {Object} base   Object to compare with
 * @param  {Object} ignoreBlanks will not include properties whose value is null, undefined, etc.
 * @return {Object}        Return a new object who represent the diff
 */
objectDifference = function (object, base, ignoreBlanks = false) {
    if (!lodash.isObject(object) || lodash.isDate(object)) return object            // special case dates
	return lodash.transform(object, (result, value, key) => {
        if (!lodash.isEqual(value, base[key])) {
            if (ignoreBlanks && du.isNullBlankOrUndefined(value) && isNullBlankOrUndefined( base[key])) return;
			result[key] = lodash.isObject(value) && lodash.isObject(base[key]) ? objectDifference(value, base[key]) : value;
		}
	});
}

@indiramuru

This comment has been minimized.

Copy link

@indiramuru indiramuru commented Mar 23, 2020

for some reason transform didnt work for me. But reduce did:
Note: using lodash version 4.17.15

import { isEqual, isObject } from 'lodash/fp';
import reduce from 'lodash/reduce';

export const difference = (object, base) => {
    return reduce(
        object,
        (result, value, key) => {
            if (!isEqual(value, base[key])) {
                result[key] = isObject(value) && isObject(base[key]) ? difference(value, base[key]) : value;
            }
            return result;
        },
        {},
    );
};
@khanhtc1202

This comment has been minimized.

Copy link

@khanhtc1202 khanhtc1202 commented Mar 24, 2020

I wonder why we're not using differenceWith

var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
 
_.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
// => [{ 'x': 2, 'y': 1 }]

works perfectly in my case, using lodash version 4.17.15

@TotallyInformation

This comment has been minimized.

Copy link

@TotallyInformation TotallyInformation commented Mar 28, 2020

I wonder why we're not using differenceWith

Perhaps because you are using an array whereas the original example was about objects?

@TeNNoX

This comment has been minimized.

Copy link

@TeNNoX TeNNoX commented Apr 7, 2020

Diff object from these do not reflect removed fields.

I extended the one from @jvanderberg to:

  • return removed fields as undefined
  • fix the nested objects (the order of base and object was mixed up 😋
  • fix some edge cases
  • unit tests

https://gist.github.com/TeNNoX/5125ab5770ba287012316dd62231b764

@Aschen

This comment has been minimized.

Copy link

@Aschen Aschen commented Apr 24, 2020

Other example who make a diff between two objects without lodash:

  • added and removed keys
  • modified values
  • flat list of changes

We use it in Kourou to spot differences between large JSON based config files for Kuzzle.

objectChanges(base, object);
{
   "aws.secretKey": "u dont say",      // value has changed
   "aws.array[1].foo": "-",                   // key was removed
   "deep.nested.object.value": "+"    // key was added 
 }

Talk is cheap, show me the code

(I adapted @NicolasLetellier code)

function keyChanges(base, object) {
  const changes = {};

  function walkObject(base, object, path = '') {
    for (const key of Object.keys(base)) {
      const currentPath = path === ''
        ? key
        : `${path}.${key}`;

      if (object[key] === undefined) {
        changes[currentPath] = '-';
      }
    }

    for (const [key, value] of Object.entries(object)) {
      const currentPath = Array.isArray(object)
        ? path + `[${key}]`
        : path === ''
          ? key
          : `${path}.${key}`;

      if (base[key] === undefined) {
        changes[currentPath] = '+';
      }
      else if (value !== base[key]) {
        if (typeof value === 'object' && typeof base[key] === 'object') {
          walkObject(base[key], value, currentPath)
        }
        else {
          changes[currentPath] = object[key];
        }
      }
    }
  }

  walkObject(base, object);

  return changes
}
Example
const base = {
  aws: {
    id: 'foobar',
    secretKey: 'nevermind',
    array: [{ foo: 42 }, { bar: 21, foo: 21 }]
  },
  deep: {
    nested: {
      object: {
        secret: 'password'
      },
    }
  }
};

const other = {
  aws: {
    id: 'foobar',
    secretKey: 'u dont say',
    array: [{ foo: 42 }, { bar: 21 }]
  },
  deep: {
    nested: {
      object: {
        secret: 'password',
        value: 'my le huong'
      },
    }
  }
};

objectChanges(base, object);
// {
//   "aws.secretKey": "u dont say",
//   "aws.array[1].foo": "-",
//   "deep.nested.object.value": "+"
// }
// Added keys are flagged with "+", removed key with "-" and key who had changed contain the new value
@lsbyerley

This comment has been minimized.

Copy link

@lsbyerley lsbyerley commented Apr 28, 2020

@Aschen how does this handle arrays within the object?

@Aschen

This comment has been minimized.

Copy link

@Aschen Aschen commented Apr 29, 2020

@lsbyerley It displayed changes between arrays like that:

{ "aws.array.1.foo": "-" }

I adapted the code so now array differences are displayed like that:

{ "aws.array[1].foo": "-" }
@sumantaparida

This comment has been minimized.

Copy link

@sumantaparida sumantaparida commented May 5, 2020

var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
 
_.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);

output is wrong

@baorv

This comment has been minimized.

Copy link

@baorv baorv commented Jul 20, 2020

Nice!!

@chtseac

This comment has been minimized.

Copy link

@chtseac chtseac commented Aug 13, 2020

@Aschen There are a few problems with the code and I have tweaked it some more.

Changes:

  • rather than '+' and '-' and newValue, the change is now in the form {[from: <>], [to: <>]} including both old and new values.
  • does not check for arrays since I don't want objectChanges(['a'], {0: 'b'}) and objectChanges({0: 'b'}, ['a']) to show the key differently; _.get([{a:[0,1]}],'0.a.1') works anyways. (also, the original snippet needs an isArray check in the first half of the code too. keyChanges({a: [0, 1]}, {a: [1]}) -> { 'a.1': '-', 'a[0]': 1 }.)
  • uses lodash functions most of the time (thus checking for ownProperties and not just all enurables; a version without this can be achieved by swapping all _.has with _.hasIn, _.entries with _.entriesIn and etc)

Issues:

  • [] and {} are treated the same just like the original code.

Also, just as an FYI, you can use _.mixin to add the function into lodash.

/**
 * Deep diff between two object-likes
 * @param  {Object} fromObject the original object
 * @param  {Object} toObject   the updated object
 * @return {Object}            a new object which represents the diff
 */
function deepDiff(fromObject, toObject) {
    const changes = {};

    const buildPath = (path, obj, key) =>
        _.isUndefined(path) ? key : `${path}.${key}`;

    const walk = (fromObject, toObject, path) => {
        for (const key of _.keys(fromObject)) {
            const currentPath = buildPath(path, fromObject, key);
            if (!_.has(toObject, key)) {
                changes[currentPath] = {from: _.get(fromObject, key)};
            }
        }

        for (const [key, to] of _.entries(toObject)) {
            const currentPath = buildPath(path, toObject, key);
            if (!_.has(fromObject, key)) {
                changes[currentPath] = {to};
            } else {
                const from = _.get(fromObject, key);
                if (!_.isEqual(from, to)) {
                    if (_.isObjectLike(to) && _.isObjectLike(from)) {
                        walk(from, to, currentPath);
                    } else {
                        changes[currentPath] = {from, to};
                    }
                }
            }
        }
    };

    walk(fromObject, toObject);

    return changes;
}

// mom I'm on lodash
_.mixin({deepDiff});
Aschen's example
const base = {
  aws: {
    id: 'foobar',
    secretKey: 'nevermind',
    array: [{ foo: 42 }, { bar: 21, foo: 21 }]
  },
  deep: {
    nested: {
      object: {
        secret: 'password'
      },
    }
  }
};

const other = {
  aws: {
    id: 'foobar',
    secretKey: 'u dont say',
    array: [{ foo: 42 }, { bar: 21 }]
  },
  deep: {
    nested: {
      object: {
        secret: 'password',
        value: 'my le huong'
      },
    }
  }
};

_.deepDiff(base, other);
// { 'aws.secretKey': { from: 'nevermind', to: 'u dont say' },
//   'aws.array.1.foo': { from: 21 },
//   'deep.nested.object.value': { to: 'my le huong' } }
@michal-databricks

This comment has been minimized.

Copy link

@michal-databricks michal-databricks commented Sep 10, 2020

Maybe not the fastest, and does not cover many features added above but quite concise and readable alternative:

const objectDiff = (a, b)  => _.fromPairs(_.differenceWith(_.toPairs(a), _.toPairs(b), _.isEqual))
@123anvar

This comment has been minimized.

Copy link

@123anvar 123anvar commented Sep 21, 2020

worked !! thanks 👍

@yogendra3236

This comment has been minimized.

Copy link

@yogendra3236 yogendra3236 commented Sep 30, 2020

That's fantastic! Thanks!

@Yimiprod

This comment has been minimized.

Copy link
Owner Author

@Yimiprod Yimiprod commented Oct 2, 2020

Thanks a lot to everyone to let that gist be alive with a lot of propositions, don't know if i have the time to update it to a newer / better version, there's a lot of good proposals !

@pc-vkaza

This comment has been minimized.

Copy link

@pc-vkaza pc-vkaza commented Oct 4, 2020

Awesome. Thanks. Perfect solution to what I am looking for.

@6youss

This comment has been minimized.

Copy link

@6youss 6youss commented Oct 6, 2020

Awesome man ! cheers from Colorado

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.