0

I have the following function that should determine which elements in a nested object were changed, deleted or added:

static modifiedDiff(o1, o2, deep = false, added = [], updated = [], removed = [], path = "", key = "") {

  path += key.length > 0 ? key + "." : '';


  for (const prop in o1) {
    if (o1.hasOwnProperty(prop)) {
      const o2PropValue = o2[prop];
      const o1PropValue = o1[prop];

      if (o2.hasOwnProperty(prop)) {
        if (o2PropValue === o1PropValue) {
          //unchanged[prop] = o1PropValue;
        } else {
          if (deep && this.isObject(o1PropValue) && this.isObject(o2PropValue)) {
            this.modifiedDiff(o1PropValue, o2PropValue, deep, added, updated, removed, path, this.modifyPropIfNeeded(prop));
          } else {
            this.addObjectToArray(updated, path + prop, o2PropValue);
          }
        }
      } else {
        this.addObjectToArray(removed, path + prop, o1PropValue);
      }
    }
  }
  for (const prop in o2) {
    if (o2.hasOwnProperty(prop)) {
      const o1PropValue = o1[prop];
      const o2PropValue = o2[prop];
      if (o1.hasOwnProperty(prop)) {
        if (o1PropValue !== o2PropValue) {
          if (!deep || !this.isObject(o1PropValue)) {
            //updated[prop].oldValue = o1PropValue;
          }
        }
      } else {
        this.addObjectToArray(added, path + prop, o2PropValue);
      }
    }
  }

  return {
    added,
    updated,
    removed
  };
}

This works fine for changes, and elements that are added to the second object. The result looks like this:

{
    "added": [
        {
            "_objects.4": {
                "type": "textbox",
                "version": "4.1.0",
                "originX": "center",
                "originY": "center",
                "left": 10,
                "top": 10,
                "width": 84.51,
                "height": 45.2,
                "fill": "#000000",
                "stroke": null,
                "strokeWidth": 1,
                "strokeDashArray": null,
                "strokeLineCap": "butt",
                "strokeDashOffset": 0,
                "strokeLineJoin": "miter",
                "strokeMiterLimit": 4,
                "scaleX": 0.5,
                "scaleY": 0.5,
                "angle": 0,
                "flipX": false,
                "flipY": false,
                "opacity": 1,
                "shadow": null,
                "visible": true,
                "backgroundColor": "",
                "fillRule": "nonzero",
                "paintFirst": "fill",
                "globalCompositeOperation": "source-over",
                "skewX": 0,
                "skewY": 0,
                "text": "hallo",
                "fontSize": 40,
                "fontWeight": "",
                "fontFamily": "helvetica",
                "fontStyle": "",
                "lineHeight": 1.16,
                "underline": false,
                "overline": false,
                "linethrough": false,
                "textAlign": "left",
                "textBackgroundColor": "",
                "charSpacing": 0,
                "minWidth": 20,
                "splitByGrapheme": false,
                "id": "text_835392",
                "styles": {}
            }
        }
    ],
    "updated": [
        {
            "_objects.1.left": 372.81
        },
        {
            "_objects.1.top": 179.99
        }
    ],
    "removed": []
}

The problem is the following: If one element in an array of o2 is deleted, every element of that array moves one index forward. This results in all elements after the deleted element to be moved into the changed or added array.

Example:

modifiedDiff([1,2,3,4], [1,2,4])

should be:

{
    "added": [],
    "updated": [],
    "removed": [
        {
            "2": 3
        }
    ]
}

but is:

{
    "added": [],
    "updated": [
        {
            "2": 4
        }
    ],
    "removed": [
        {
            "3": 4
        }
    ]
}

Any ideas? Thanks for your help!

Barmar
  • 741,623
  • 53
  • 500
  • 612
SkisprungGott
  • 62
  • 1
  • 5
  • 2
    I suggest you google "how do diff algorithms work" to learn the general design. You have to match sequences, not just individual array elements. – Barmar Oct 22 '21 at 20:16
  • 1
    i think you will find [this Q&A](https://stackoverflow.com/a/33233053/633183) to be helpful – Mulan Oct 23 '21 at 03:03

0 Answers0