Niklesh Raut
Niklesh Raut

Reputation: 34914

How to check if values in one JavaScript object are present in another one?

I am trying to compare json_str1 and json_str2, here it should return true as all elements in json_str1 are present in json_str2.

For now I am doing this the long way like this

json_str1 = '{"0":"a","1":"b","2":"c"}';
json_str2 = '{"0":"c","1":"b","2":"a"}';

json_obj1 = $.parseJSON(json_str1);
json_obj2 = $.parseJSON(json_str2);

arr1 = $.map(json_obj1, function(el) { return el });
arr2 = $.map(json_obj2, function(el) { return el });

if($(arr1).not(arr2).length === 0 && $(arr2).not(arr1).length === 0)
    alert("equal");
else
    alert("not equal");

How could I make it short and simple, without converting the objects into an array ?

https://jsfiddle.net/kq9gtdr0/

Upvotes: 15

Views: 10454

Answers (8)

ilmoi
ilmoi

Reputation: 2534

Extending the awesome answer by @user663031, in case you need to do deep comparison, here's code that works:

export function objectOneInsideObjectTwo(jsonObj1: any, jsonObj2: any): boolean {
  return Object.keys(jsonObj1).every((k1) => {
    if (parseType(jsonObj1[k1]) === 'dict') {
      return objectOneInsideObjectTwo(jsonObj1[k1], jsonObj2[k1]);
    }
    if (parseType(jsonObj1[k1]) === 'array') {
      const results: boolean[] = [];
      jsonObj1[k1].forEach((o: any, i: number) => {
        if (parseType(o) === 'dict') {
          results.push(objectOneInsideObjectTwo(o, jsonObj2[k1][i]));
        } else {
          results.push(o === jsonObj2[k1][i]);
        }
      });
      return results.every((r) => r);
    }
    return Object.keys(jsonObj2).some((k2) => jsonObj1[k1] === jsonObj2[k2]);
  });
}

export function parseType<T>(v: T): string {
  if (v === null || v === undefined) {
    return 'null';
  }
  if (typeof v === 'object') {
    if (v instanceof Array) {
      return 'array';
    }
    if (v instanceof Date) {
      return 'date';
    }
    return 'dict';
  }
  return typeof v;
}

Upvotes: 0

Tony
Tony

Reputation: 992

In your question and comments you indicate you are only looking to verify that "all elements in json_str1 are present in json_str2". Your example code doesn't just do that, it checks for the complete equality of keys by testing if all the keys (not values) in the first object are in the second object AND all the keys in the second object are in the first object. By looking at your code, i assume that when you say "elements" you mean keys.

All that aside, this might help:

// Your first few lines of code

json_str1 = '{"0":"a","1":"b","2":"c"}';
json_str2 = '{"0":"c","1":"b","2":"a"}';

json_obj1 = $.parseJSON(json_str1);
json_obj2 = $.parseJSON(json_str2);

// My new code

var values1 = Object.keys(json_obj1).map(key => json_obj1[key]);
var values2 = Object.keys(json_obj2).map(key => json_obj2[key]);

// Check if every key in the first object is in the second object.
values1.every(k1 => values2.indexOf(k1) >= 0);

// OR

// Check for equality of keys by checking both directions.
values1.every(k1 => values2.indexOf(k1) >= 0) && values2.every(k2 => values1.indexOf(k2) >= 0);

That's 2 lines to get the keys, and one line to check. You only need one of those two checks.

Upvotes: -1

user663031
user663031

Reputation:

Use the following code:

Object.keys(json_obj1) . every(k1 => 
  Object.keys(json_obj2) . some(k2 =>
    json_obj1[k1] === json_obj2[k2]
  )
);

In English:

Every key k1 in json_obj1 satisfies the condition that some key k2 in json_obj2 satisifies the condition that the value of json_obj1 with key k1 is equal to the value of json_obj2 with key k2.

Or in more conversational English:

Every value in the first object matches some value in the second.

Upvotes: 13

Lux
Lux

Reputation: 18240

If you want to find out if both Objects have the same keys there is no way to do this without at least converting the keys of both Objects to an array with Object.keys or looping through both Objects!

The reason is simple: It's clear that you have to compare the number of keys of both Objects and the only way to do this is by looping through all properties or Object.keys.

So I think the shortest way to do this is:

json_obj1 = JSON.parse('{"0":"a","1":"b","2":"c"}');
json_obj2 = JSON.parse('{"0":"c","1":"b","2":"a"}');

keys_1 = Object.keys(json_obj1);
keys_2 = Object.keys(json_obj2);

if(keys_1.length === keys_2.length && keys_1.every(key => keys_2.indexOf(key) >= 0)) {
    alert('equal')
} else {
    alert('not equal')
}

If you only want to check if all keys from json1 are present in json2 you can do:

json_obj1 = JSON.parse('{"0":"a","1":"b","2":"c"}');
json_obj2 = JSON.parse('{"0":"c","1":"b","2":"a"}');
if(Object.keys(json_obj1).every(key => key in json_obj2)) {
  alert('equal');
} else {
  alert('not equal');
}

Upvotes: -1

nilesh
nilesh

Reputation: 14287

If you prefer using libraries, then you could use underscore isMatch

_.isMatch(object, properties)

Tells you if the keys and values in properties are contained in object.

Upvotes: 1

manonthemat
manonthemat

Reputation: 6251

Using lodash

var _ = require('lodash');

function compareValues(jstr1, jstr2) {
  return _.isEqual(_.valuesIn(JSON.parse(jstr1)).sort(), _.valuesIn(JSON.parse(jstr2)).sort());
}

json_str1 = '{"0":"a","1":"b","2":"c"}';
json_str2 = '{"0":"c","1":"b","2":"a"}';

console.log(compareValues(json_str1, json_str2));

Upvotes: 2

Nidhin David
Nidhin David

Reputation: 2474

There is short and easy accurate way to this.

You can use a third party but extremely popular utility library called Lodash. Chaining functions you can check for equality.

  1. First parse both JSON into objects
  2. Then use _.values() to extract the values of all keys of each into separate arrays
  3. Find difference of two arrays. If its an empty array then both of them are equal.

You can chain all the steps into one statement like:

_.isEmpty(_.difference(_.values(json_obj1), _.values(json_obj2)))

Example: https://jsfiddle.net/kq9gtdr0/4/

For more information:

https://lodash.com/docs#values

https://lodash.com/docs#difference

https://lodash.com/docs#isEmpty

You can include the library from CDN(https://cdn.jsdelivr.net/lodash/4.5.1/lodash.min.js) or download and use it as normal script. Lodash offers plenty of useful utility functions that makes JS programming a lot easier. You better try it out.

Upvotes: 1

Atul Agrawal
Atul Agrawal

Reputation: 1520

You can try this

var json_str1 = {"0":"a","1":"b","2":"c"};
var json_str2 = {"0":"c","1":"b","2":"a"};
var flag =  1;

if(Object.keys(json_str1).length == Object.keys(json_str2).length){
    Object.keys(json_str1).forEach(function(x){
        if(!json_str2.hasOwnProperty(x) || json_str2[x] != json_str1[x]){
            flag = 0;
            return;
        }                      
    });
}

if(flag)
    alert('equal');
else
    alert('Not Equal');

Upvotes: -1

Related Questions