3

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.

11
  • 2
    Please see this answer: stackoverflow.com/questions/1068834/… Commented Jun 4, 2014 at 8:38
  • In Node: require('assert').deepEqual(x,y) Commented Jun 4, 2014 at 8:38
  • meaning You want to make sure that y have "dummy1" and "dummy2" as x have? While exact values are not important? Commented Jun 4, 2014 at 8:39
  • 2
    @Hawk: it is a link to another SO question... Commented Jun 4, 2014 at 8:41
  • 1
    @Hawk no it's not. It's good to discourage duplicate questions and answers. Commented Jun 4, 2014 at 8:45

6 Answers 6

5

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);
}
Sign up to request clarification or add additional context in comments.

6 Comments

@JL - Can I ask would this also work and return false if either x or y were null or equal to the empty string?
@Melina It will now. :)
@JL - Thanks for your very clear and simple solution that uses superItem :-)
Just fixed an issue. super is a reserved keyword in JavaScript.
Uh, shouldn't it be if (!x || !y) return false;? You seem to still allow the case where one of them is falsy.
|
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..
      }
   }
  }

1 Comment

What if y has more keys than x?
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.

2 Comments

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 That is exactly the point, avoiding inherited properties.
0

Try this:

Object.keys(y).every(function (key) {
    return key in x;
});

3 Comments

What if x has more keys than y?
Then it's considered different and I need it to return false.
If you also want to make sure x doesn't contain any keys that are not present in y, then you just have to do the same check with the variables reversed.
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;
}

Comments

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

4 Comments

Are you sure keys will return the keys in the same order for both the objects?
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.
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.
Well then we can bite the bullet and sort them all.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.