-1

I have two JSON objects and want to return 'true' value if the key and values matches. All the three values should match for both d1 and d2.

var d1 = [{"deviceid":"867874031097770","simno":"232ff33","slot":"1"},{"deviceid":"86787403100","simno":"ss343433","slot":"2"}];

var d2 = {"deviceid":"867874031097770","simno":"232ff33","slot":"1"};

I have tried using the following code but not working for array of JSON values.

function equals ( x, y ) {
    // If both x and y are null or undefined and exactly the same
    if ( x === y ) {
        return true;
    }

    // If they are not strictly equal, they both need to be Objects
    if ( ! ( x instanceof Object ) || ! ( y instanceof Object ) ) {
        return false;
    }

    // They must have the exact same prototype chain, the closest we can do is
    // test the constructor.
    if ( x.constructor !== y.constructor ) {
        return false;
    }

    for ( var p in x ) {
        // Inherited properties were tested using x.constructor === y.constructor
        if ( x.hasOwnProperty( p ) ) {
            // Allows comparing x[ p ] and y[ p ] when set to undefined
            if ( ! y.hasOwnProperty( p ) ) {
                return false;
            }

            // If they have the same strict value or identity then they are equal
            if ( x[ p ] === y[ p ] ) {
                continue;
            }

            // Numbers, Strings, Functions, Booleans must be strictly equal
            if ( typeof( x[ p ] ) !== "object" ) {
                return false;
            }

            // Objects and Arrays must be tested recursively
            if ( !equals( x[ p ],  y[ p ] ) ) {
                return false;
            }
        }
    }

    for ( p in y ) {
        // allows x[ p ] to be set to undefined
        if ( y.hasOwnProperty( p ) && ! x.hasOwnProperty( p ) ) {
            return false;
        }
    }
    return true;
}
vishnu
  • 4,377
  • 15
  • 52
  • 89
  • 1
    what result do you expect? btw, i see no [JSON](http://json.org/), but an array of objects and an object. – Nina Scholz Apr 25 '19 at 15:47
  • I usually stringify my objects and use a strict comparison operator – Kevin Coulibaly Apr 25 '19 at 15:48
  • JSON is a *textual notation* for data exchange. [(More here.)](http://stackoverflow.com/a/2904181/157247) If you're dealing with JavaScript source code, and not dealing with a *string*, you're not dealing with JSON. – T.J. Crowder Apr 25 '19 at 15:51
  • Duplicate of https://stackoverflow.com/questions/201183/how-to-determine-equality-for-two-javascript-objects – T.J. Crowder Apr 25 '19 at 15:53
  • D1 is an array of objects, D2 is a single object. Comparing them directly won't work. What you effectively want to evaluate is "Is D2 _contained within_ D1". – Lewis Apr 25 '19 at 15:57

4 Answers4

1

You could get all keys and chekc the existence in both objects and their values.

If one of the objects of the array matches with the given object, you could use Array#some.

function compare(a, b) {
    return [...new Set([...Object.keys(a), ...Object.keys(b)])]
        .every(k => k in a && k in b && a[k] === b[k]);
}

var d1 = [{ deviceid: "867874031097770", simno: "232ff33", slot: "1" },{ deviceid: "86787403100", simno: "ss343433", slot: "2" }],
    d2 = { deviceid: "867874031097770", simno: "232ff33", slot: "1" },
    result = d1.map(compare.bind(null, d2)),
    isMatching = d1.some(compare.bind(null, d2));

console.log(isMatching);
console.log(result);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

They must have the exact same prototype chain, the closest we can do is test the constructor.

Actually, you can test the prototype:

if (Object.getPrototypeOf(x) !== Object.getPrototypeOf(y)) {
    return false;
}

It sounds like you want:

  1. To be objects: typeof x === "object" is the best way to check
  2. Them to have the same prototype chain: see above
  3. To have exactly the same properties: you can use for-in for all enumerable properties, or getOwnPropertyNames for all string-named properties (including non-enumerable), or getOwnPropertySymbols for all Symbol-named properties (including non-enumerable), or Reflect.ownKeys for both string-named and Symbol-named properties
  4. A shallow comparison

If so, something along these lines should get you started:

function equals(x, y) {
    // If both x and y are null or undefined and exactly the same
    if (x === y) {
        return true;
    }

    // If they are not strictly equal, they both need to be Objects
    if (typeof x !== "object" || typeof y !== "object") {
        return false;
    }

    // Can't compare `null` with non-`null`
    if (!x || !y) { // This works because we did the `x === y` check earlier)
        return false;
    }

    // They must have the exact same prototype chain
    if (Object.getPrototypeOf(x) !== Object.getPrototypeOf(y)) {
        return false;
    }

    // Compare own properties (including non-enumerable ones)
    const xkeys = Reflect.ownKeys(x);
    const ykeys = Reflect.ownKeys(y);
    if (xkeys.length !== ykeys.length) {
        return false;
    }
    for (const key of xkeys) {
        if (!ykeys.includes(key) || x[key] !== y[key]) {
            return false;
        }
    }

    return true;
}

Live Example:

function equals(x, y) {
    // If both x and y are null or undefined and exactly the same
    if (x === y) {
        return true;
    }

    // If they are not strictly equal, they both need to be Objects
    if (typeof x !== "object" || typeof y !== "object") {
        return false;
    }

    // Can't compare `null` with non-`null`
    if (!x || !y) { // This works because we did the `x === y` check earlier)
        return false;
    }

    // They must have the exact same prototype chain
    if (Object.getPrototypeOf(x) !== Object.getPrototypeOf(y)) {
        return false;
    }

    // Compare own properties (including non-enumerable ones)
    const xkeys = Reflect.ownKeys(x);
    const ykeys = Reflect.ownKeys(y);
    if (xkeys.length !== ykeys.length) {
        return false;
    }
    for (const key of xkeys) {
        if (!ykeys.includes(key) || x[key] !== y[key]) {
            return false;
        }
    }

    return true;
}

const d1 = [{ deviceid: "867874031097770", simno: "232ff33", slot: "1" },{ deviceid: "86787403100", simno: "ss343433", slot: "2" }];
const d2 = { deviceid: "867874031097770", simno: "232ff33", slot: "1" };

for (const [index, entry] of d1.entries()) {
    console.log(`${index}: ${equals(entry, d2)}`);
}

It doesn't check inherited properties, though. If you wanted to do that, you'd probably have a helper function like this to get all properties:

function getAllPropertyKeys(obj) {
    const result = new Set();
    while (obj && obj !== Object.prototype) {
        for (const key of Reflect.ownKeys(obj)) {
            result.add(key);
        }
        obj = Object.getPrototypeOf(obj);
    }
    return [...result];
}

...then use that instead of Reflect.ownKeys.

Live Example:

function getAllPropertyKeys(obj) {
    const result = new Set();
    while (obj && obj !== Object.prototype) {
        for (const key of Reflect.ownKeys(obj)) {
            result.add(key);
        }
        obj = Object.getPrototypeOf(obj);
    }
    return [...result];
}

function equals(x, y) {
    // If both x and y are null or undefined and exactly the same
    if (x === y) {
        return true;
    }

    // If they are not strictly equal, they both need to be Objects
    if (typeof x !== "object" || typeof y !== "object") {
        return false;
    }

    // Can't compare `null` with non-`null`
    if (!x || !y) { // This works because we did the `x === y` check earlier)
        return false;
    }

    // They must have the exact same prototype chain
    if (Object.getPrototypeOf(x) !== Object.getPrototypeOf(y)) {
        return false;
    }

    // Compare own properties (including non-enumerable ones)
    const xkeys = getAllPropertyKeys(x);
    const ykeys = getAllPropertyKeys(y);
    if (xkeys.length !== ykeys.length) {
        return false;
    }
    for (const key of xkeys) {
        if (!ykeys.includes(key) || x[key] !== y[key]) {
            return false;
        }
    }

    return true;
}

const d1 = [{ deviceid: "867874031097770", simno: "232ff33", slot: "1" },{ deviceid: "86787403100", simno: "ss343433", slot: "2" }];
const d2 = { deviceid: "867874031097770", simno: "232ff33", slot: "1" };

for (const [index, entry] of d1.entries()) {
    console.log(`${index}: ${equals(entry, d2)}`);
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

You can stringify d2 and compare with each entry in d1. Just make sure that the order is maintained when you stringify your objects by providing a replacer function as a second parameter in JSON.stringify.

Properties of non-array objects are not guaranteed to be stringified in any particular order. Do not rely on ordering of properties within the same object within the stringification.

function replacer(obj) {
  return Object.keys(obj).sort();
}

var d1 = [{"deviceid":"867874031097770", "simno":"ss343433", "slot":"1"}, 
          {"deviceid":"867874031097770","simno":"ss343433","slot":"1"}];

var d2 = {"deviceid":"867874031097770","slot":"1", "simno":"ss343433"};

function equals(searchArr, objToCheck) {
  var allEqual = true;
  for (index in searchArr) {
    const item = searchArr[index];
    if (JSON.stringify(item, replacer(item)) !== JSON.stringify(objToCheck, replacer(objToCheck))) {
      (objToCheck)));
      allEqual = false;
      break;
    }
  }
  return allEqual;
}

if (equals(d1, d2)) {
  console.log('All values of properties of d2 match with all entries in d1')
} else {
  console.log('d2 values do not match with all entries in d1');
}
Hassaanz
  • 182
  • 9
-1

You can stringify and just compare both jsons.

JSON.stringify(d1) == JSON.stringify(d2)
kumar gaurav
  • 59
  • 10
  • 1
    should be `===` – chevybow Apr 25 '19 at 15:53
  • 3
    This is a **very bad idea**. Note that `JSON.stringify({a: 1, b: 2}) !== JSON.stringify({b: 2, a: 1})` (and that's per spec). The order of creation of the properties dictates the order of the properties in the string. – T.J. Crowder Apr 25 '19 at 15:53