0

I'm trying to build an algorithm which can output the difference between two objects. I can't figure out how to create an array when the typeof object is an array. I know it has to do with the the first key returned when enumerating the array is the index as a string; "0". So it's assigning "0" as an object instead of the array.

    function difference(o1, o2) {

                var k;
                var kDiff;
                var diff = {};

                for (k in o1)
                {
                    if (!o1.hasOwnProperty(k)) { }
                    else if (typeof o1[k] != 'object' || typeof o2[k] != 'object')
                    {
                        if (!(k in o2) || o1[k] !== o2[k]){
                            diff[k] = o2[k];
                        }
                    } else if (kDiff = difference(o1[k], o2[k]))
                    {
                        diff[k] = kDiff;
                    }
                }
                for (k in o2)
                {
                    if (o2.hasOwnProperty(k) && (!o1 || !(k in o1)))
                    {
                        diff[k] = o2[k];
                    }
                }
                for (k in diff)
                {
                    if (diff.hasOwnProperty(k))
                    {
                        return diff;
                    }
                }

                return false;
            }

Test Case

    var lhs = {
        "Id": 1,
        "Type" : "Mortgage",
        "Amount": 500000,
        "Rate" : .045,
        "Borrowers": [
            {
                "Id": 1,
                "FirstName": "Jon",
                "Employment": [
                    {
                        "Id": 1,
                        "Employer": "Walmart",
                        "Income": [
                            {
                                "Id": 1,
                                "MonthlyIncome": 5000,
                                "Type": "Base"
                            },
                            {
                                "Id": 2,
                                "MonthlyIncome": 1000,
                                "Type": "Overtime"
                            }
                        ]
                    }
                ]

            }

        ]
    }
    var rhs = {
        "Id": 1,
        "Type" : "Mortgage",
        "Amount": 500001,
        "Rate" : .045,
        "Borrowers": [
            {
                "Id": 1,
                "FirstName": "Don",
                "Employment": [
                    {
                        "Id": 1,
                        "Employer": "Walmart",
                        "Income": [
                            {
                                "Id": 1,
                                "MonthlyIncome": 5000,
                                "Type": "Base"
                            },
                            {
                                "Id": 2,
                                "MonthlyIncome": 500,
                                "Type": "Other"
                            }
                        ]
                    }
                ]

            }

        ]
    }

    var changes = JSON.stringify(difference(lhs, rhs);

Expected Result:

{
    "Amount": 500001,
    "Borrowers": [
        {
            "FirstName": "Don",
            "Employment": [
                {
                    "Income": [
                        {
                            "MonthlyIncome": 500,
                            "Type": "Other"
                        }
                    ]
                }
            ]
        }
    ]
}

Not:

{
    "Amount": 500001,
    "Borrowers": {
        "0": {
            "FirstName": "Don",
            "Employment": {
                "0": {
                    "Income": {
                        "1": {
                            "MonthlyIncome": 500,
                            "Type": "Other"
                        }
                    }
                }
            }
        }
    }
}
1
  • 2
    just hints: typeof [] returns 'object' and not 'array' (use Array.isArray instead). Then you define diff = {} so you can't have an array here.. Commented Nov 9, 2018 at 14:51

2 Answers 2

1

I'm a little confused by what you are trying to do, but if lodash is an option to use, does this help?

function difference(base, object) {
  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);
}
Sign up to request clarification or add additional context in comments.

2 Comments

I didn't know about this functionality in lodash. I have another requirement which is to always include the 'Id' field and value, if any of the other field values are changed in an object. Is there a way to this with lodash transform?
@ddrjca you have key and value in function(result, value, key), so yes, you just need to test if key === 'Id' and assign it to result if the case
0

Based the hint from @Kaddath, the returned differences must be defined based on the object type being evaluated:

function difference(o1, o2) {

  var k;
  var kDiff;
  var diff = Array.isArray(o1) ? [] : {};

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.