Georgi Kirilov
Georgi Kirilov

Reputation: 599

Compare 2 objects and remove repeating keys between

I am experimenting on objects, and what I am trying to achieve is to remove keys found in object1 if those keys exist in object2.

Here is the example:

var original = {
    a: 1, 
    b: 2, 
    c: 3,
    e: {
        tester: 0,
        combination: {
            0: 1
        }
    },
    0: {
        test: "0",
        2: "hello"
    }
};

var badKeys = {
    a: 1,
    b: 2,
    0: {
        test: "0",
    }
}


var expectedResult = {
    c: 3,
    e: {
        tester: 0, 
        combination: {
            0: 1
        }
    },
    0: {
        2: "hello"
    }

}

I've tried using underscore difference function, but it doesn't work for objects, also not sure if this is the right function.

Can you help me to get the var expectedResult right?

Upvotes: 2

Views: 991

Answers (4)

Telcrome
Telcrome

Reputation: 369

Truly a job for some recursion and a bit of functional programming using a pure function. (Tested with Node v7.7.1)

"DoForAllNestedObjects" for applying some function "whattodo" on "every leaf on the dictionary tree" when there is an corresponding "leaf" in baddict.

let DoForAllNestedValues = (dict, baddict, whattodo) => {
    for (let key in dict) {
        if (typeof (dict[key]) === 'object' && typeof (baddict[key]) === 'object')
            DoForAllNestedValues(dict[key], baddict[key], whattodo);
        else
            if (baddict[key])
                whattodo(dict, key);
    }
}

DoForAllNestedValues(original, badKeys, (obj, val) => delete obj[val]);
console.log(original);

Upvotes: 0

Nenad Vracar
Nenad Vracar

Reputation: 122047

You can create recursive function that will return new object using for...in loop.

var original = {"0":{"2":"hello","test":"0"},"a":1,"b":2,"c":3,"e":{"tester":0,"combination":{"0":1}}}
var badKeys = {"0":{"test":"0"},"a":1,"b":2}

function remove(o1, o2) {
  var result = {}
  for (var i in o1) {
    if (!o2[i]) result[i] = o1[i]
    else if (o2[i]) {
      if (typeof o1[i] == 'object' && typeof o2[i] == 'object') {
        result[i] = Object.assign(result[i] || {}, remove(o1[i], o2[i]))
      } else if (o1[i] != o2[i]) result[i] = o1[i]
    }
  }
  return result
}


console.log(remove(original, badKeys))

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386604

You could use an iterative and recursive approach for geeting the wanted properties in a new object.

function deleteKeys(good, bad, result) {
    Object.keys(good).forEach(function (key) {
        if (bad[key] && typeof bad[key] === 'object') {
            result[key] = {};
            deleteKeys(good[key], bad[key], result[key]);
            return;
        }
        if (!(key in bad) || good[key] !== bad[key]) {
            result[key] = good[key];
        }
    });
}

var original = { a: 1, b: 2, c: 3, e: { tester: 0, combination: { 0: 1 } }, 0: { test: "0", 2: "hello", another: { a: { B: 2, C: { a: 3 } }, b: 2 } } },
    badKeys = { a: 1, b: 2, 0: { test: "0", random: 2, another: { a: 1 } } },
    result = {};

deleteKeys(original, badKeys, result);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

nitobuendia
nitobuendia

Reputation: 1248

This would be the algorithm:

function removeDifferences (original, removeKeys) {
  // Get keys of to be deleted properties.
  var keys = Object.keys(removeKeys);

  // Iterate all properties on removeKeys.
  for (key of keys) {
    // Check if property exists on original.
    if (typeof original[key] !== undefined) {
      // If the property is an object, call same function to remove properties.
      if (typeof removeKeys[key] === 'object') {
        removeDifferences(original[key], removeKeys[key]);
      } else {
        delete original[key];
      }
    }
  }
  return original;
}

Applied to your case:

/* Your data. */

var original = {
  a: 1,
  b: 2,
  c: 3,
  e: {
    tester: 0,
    combination: {
      0: 1
    }
  },
  0: {
    test: "0",
    2: "hello"
  }
};

var badKeys = {
  a: 1,
  b: 2,
  0: {
    test: "0",
  }
};

var expectedResult = {
  c: 3,
  e: {
    tester: 0,
    combination: {
      0: 1
    }
  },
  0: {
    2: "hello"
  }

};

/* Function */

function removeDifferences(original, removeKeys) {
  // Get keys of to be deleted properties.
  var keys = Object.keys(removeKeys);

  // Iterate all properties on removeKeys.
  for (key of keys) {
    // Check if property exists on original.
    if (typeof original[key] !== undefined) {
      // If the property is an object, call same function to remove properties.
      if (typeof removeKeys[key] === 'object') {
        removeDifferences(original[key], removeKeys[key]);
      } else {
        delete original[key];
      }
    }
  }
  return original;
}

/* Application */
var output = removeDifferences(original, badKeys);
console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 0

Related Questions