2

Given:

I have the following two variables in Javascript:

var x = {
            dummy1: null
            dummy2: null
        };

// Return true
var y = {
            dummy1: 99,
            dummy2: 0
        }

// Return false
var y = "";


// Return false
var y = {
            dummy1: null
        };

// Return false
var y = {
            dummy1: null,
            dummy2: null,
            dummy3: 'z'
        }

// Return false
var y = null;

// Return false
var y = ""

Can anyone suggest to me how I can check if object x has the same field names as y ? Note that I am not checking the values of the parameters.

  • 2
    Please see this answer: http://stackoverflow.com/questions/1068834/object-comparison-in-javascript – hsiegeln Jun 04 '14 at 08:38
  • In Node: `require('assert').deepEqual(x,y)` – elclanrs Jun 04 '14 at 08:38
  • meaning You want to make sure that y have "dummy1" and "dummy2" as x have? While exact values are not important? – przemo_li Jun 04 '14 at 08:39
  • @hsiegeln, whereas that could be the answer to the OP's question, it is always good to write the answer here in case the link changes. – Hawk Jun 04 '14 at 08:40
  • 2
    @Hawk: it is a link to another SO question... – elclanrs Jun 04 '14 at 08:41
  • i know that but i'm saying that it is good practice @hsiegeln – Hawk Jun 04 '14 at 08:43
  • @Hawk Actually, if the content of that link serves as an answer to this question, then the good practice is to mark this one as a duplicate and point to that one. But I suspect that the question here is actually somewhat different from that one. – JLRishe Jun 04 '14 at 08:44
  • 1
    @Hawk no it's not. It's good to discourage duplicate questions and answers. – Ankit Jaiswal Jun 04 '14 at 08:45
  • @AnkitJaiswal - I'm checking for fields. Not for fields with the same values. –  Jun 04 '14 at 08:46
  • Sorry for my delay in updating my question to make it more clear. My laptop battery ran out just when I was about to make the question more clear. What I need to do is to check field names. If there are 5 names in x then I need to check y is an object with fields and then see if those exact same field names appear in variable y. –  Jun 04 '14 at 08:52
  • @Melina Do you want to include inherited properties in the comparison or just use "own" properties? And what should the result be if either of the inputs is a number, nonempty string or boolean? – JLRishe Jun 04 '14 at 09:33

6 Answers6

4

in javascript, every object contains elements as array. for e.g.

   var bequal = true;

   if(Object.keys(x).length !== Object.keys(y).length) {
        bequal = false;
    }
    else {
   for (var prop in x) {
      if(!y.hasOwnProperty(prop)){
          bequal = false;
          break;
          //both objects are not equal..
      }
   }
  }
Kartik626
  • 91
  • 6
4

There are probably better names for these functions, but this should do it:

function hasAllProperties(subItem, superItem) {
    // Prevent error from using Object.keys() on non-object
    var subObj = Object(subItem),
        superObj = Object(superItem);

    if (!(subItem && superItem)) { return false; }

    return Object.keys(subObj).every(function (key) {
        return key in superObj;
    });
}

function allPropertiesShared(x, y) {
    return hasAllProperties(x, y) && 
           hasAllProperties(y, x);
}
JLRishe
  • 99,490
  • 19
  • 131
  • 169
2
function hasSameKeys(obj1, obj2) {
    var toString = Object.prototype.toString;
    if (toString.call(obj1).indexOf("Object") === -1
        || toString.call(obj2).indexOf("Object") === -1) {
        return false;
    }
    var keys1 = Object.keys(obj1), keys2 = Object.keys(obj2);

    return obj1.length === obj2.length && 
        keys1.every(function(currentKey) {
            return obj2.hasOwnProperty(currentKey);
    });
}

console.assert(hasSameKeys({a:1, b:2}, {b:3, a:1}) === true);
console.assert(hasSameKeys({a:1, b:2}, "")         === false);
console.assert(hasSameKeys({a:1, b:2}, {a:5})      === false);

The toString check makes sure that the objects being compared are really "Objects", not strings.

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
  • 1
    I think you meant to use `keys1.length` and `keys2.length`? `obj1.length` is `undefined` in this case. And perhaps it's better to use `in` than `hasOwnProperty`, as that will check inherited keys. – JLRishe Jun 04 '14 at 09:08
  • 2
    @JLRishe That is exactly the point, avoiding inherited properties. – thefourtheye Jun 04 '14 at 09:08
0

Try this:

Object.keys(y).every(function (key) {
    return key in x;
});
jupenur
  • 1,005
  • 6
  • 8
0

Use Object.keys()

Here's a simple example to show how this works:

$ nodejs // should also work in Browser
> x = {a:1,b:2,c:3}
{ a: 1, b: 2, c: 3 }
> y = {a:3,b:1,c:4}
{ a: 3, b: 1, c: 4 }
> z={message:"Die Batman!"}   // one of these things is not like the others
{ message: 'Die Batman!' }

> Object.keys(x)
[ 'a', 'b', 'c' ]
> Object.keys(y)
[ 'a', 'b', 'c' ]
> Object.keys(z)
[ 'message' ]

Don't compare Object.keys directly as they are arrays and will not ===

> Object.keys(x)===Object.keys(y)
false

Also, Object.keys() might give a different ordering in the array, resulting in unequal arrays like ['a','b','c'] vs ['b','a','c']. Fix for this is to add Array.sort()

I suggest using JSON.stringify to create string representations of the key lists

> JSON.stringify(Object.keys(x).sort())===JSON.stringify(Object.keys(y).sort())
true

> JSON.stringify(Object.keys(x).sort())===JSON.stringify(Object.keys(z).sort())
false
Paul
  • 26,170
  • 12
  • 85
  • 119
  • 1
    Are you sure `keys` will return the keys in the same order for both the objects? – thefourtheye Jun 04 '14 at 08:50
  • Docs says "returns an array of a given object's own enumerable properties, in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well)." so... maybe... I wondered this too. – Paul Jun 04 '14 at 08:51
  • 1
    No, I'm pretty sure we can't count on the properties to be in the same order. `for...in` doesn't guarantee any particular order, and the only guarantee of `Object.keys()` is that it will be in the same (implementation specific) order as `for...in`. – JLRishe Jun 04 '14 at 08:54
  • Well then we can bite the bullet and sort them all. – Paul Jun 04 '14 at 08:56
0

You can try something like this

var isEqual = true;
for(var k in x)
{
    if(x[k] != y[k])
        isEqual = false;
}
for(var k in y)
{
    if(x[k] != y[k])
        isEqual = false;
}
Ted Xu
  • 1,095
  • 1
  • 11
  • 20