Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare a String to a Key in a JavaScript Object

How do I compare a string to a JavaScript object's key? For example, here is a string and a JavaScript object. I want to compare the string (in this case, the value of myString is "Item1") to a key in this JavaScript object (in this case, the keys are Item1 and Item2):

var myString = "Item1";

var jsObject = 
{
    Item1:
    {
        "apples": "red",
        "oranges": "orange",
    },
    Item2:
    {
        "bananas": "yellow",
        "pears": "green"
    }
};

If I create a 'for' loop and run the contents of object through the loop, I want to compare the keys in this object to a string.

for (var x = 0; x < Object.keys(jsObject).length; x++)
{
    if (myString == /* What do I put here to compare to grab Item1 or Item2? */)
    {
        // Do stuff
    }
}
like image 262
HuskyBlue Avatar asked Nov 18 '16 17:11

HuskyBlue


4 Answers

You don't need a loop for this and shouldn't use one. Instead, reference the object property directly. This is simpler and faster:

var myString = "Item1";

var jsObject = {
    Item1: {
        "apples": "red",
        "oranges": "orange",
    },
    Item2: {
        "bananas": "yellow",
        "pears": "green"
    }
};

var item;
if( jsObject.hasOwnProperty(myString) ) {
    item = jsObject[myString];
    console.log( item );
}

Also, I have a stylistic recommendation if you don't mind. You may note that in the code snippet above I moved the open curly braces to the end of the line above instead of a line of their own.

In most "curly brace" languages, this is merely a coding style choice that doesn't affect how the code is compiled and run. However, because of JavaScript's automatic semicolon insertion, putting the open brace on its own line can break your code. Here's an example:

function good() {
    return {
        foo: 'bar'
    }
}

console.log( 'good:', good() );

function bad()
{
    return
    {
        foo: 'bar'
    }
}

console.log( 'bad:', bad() );

The good() and bad() functions look like they should return the same result, the { foo: 'bar' } object. That's because automatic semicolon insertion changes the bad() function to this:

function bad()
{
    return;  // <-- semicolon added, so it returns undefined, not the object
    {
        foo: 'bar'
    }
}

Because of this I recommend the "open brace at the end of the line" style for all JavaScript code.

like image 185
Michael Geary Avatar answered Nov 11 '22 16:11

Michael Geary


var myString = "Item1";

var jsObject = 
{
    Item1:
    {
        "apples": "red",
        "oranges": "orange",
    },
    Item2:
    {
        "bananas": "yellow",
        "pears": "green"
    }
};

var keys = Object.keys(jsObject); //get keys from object as an array

keys.forEach(function(key) { //loop through keys array
  console.log(key, key == myString)
});

You could use a for loop, but you'd have to store the array of keys somewhere.

var myString = "Item1";

var jsObject = 
{
    Item1:
    {
        "apples": "red",
        "oranges": "orange",
    },
    Item2:
    {
        "bananas": "yellow",
        "pears": "green"
    }
};

var keys = Object.keys(jsObject);

for (var i = 0; i < keys.length; i++) {
  if (myString == keys[i])
    console.log('match: ', keys[i])
}

Optionally, you can use for..in to get the keys as well.

var myString = "Item1";

var jsObject = 
{
    Item1:
    {
        "apples": "red",
        "oranges": "orange",
    },
    Item2:
    {
        "bananas": "yellow",
        "pears": "green"
    }
};

for (var key in jsObject) {
  console.log(key, key == myString)  
}
like image 45
Gavin Avatar answered Nov 11 '22 17:11

Gavin


Directly test that the string is a property using .hasOwnProperty()

A better way is to test directly that the string is a property on the Object with Object.prototype.hasOwnProperty(). The .hasOwnProperty() method returns a boolean indicating if the object has the string as a direct property of the object. I does not indicate true if the property exists on the objects prototype. This is equivalent to testing that the string is an entry in Object.keys() as that method returns only the objects own properties, which are enumerable. If you are concerned about the property being enumerable, then you can also use Object.prototype.propertyIsEnumerable() to test that the property is also enumerable.

Using this will be faster than creating the array of keys with Object.keys() and searching that array.

var myString = "Item1";

var jsObject = {
    Item1: {
        "apples": "red",
        "oranges": "orange",
    },
    Item2: {
        "bananas": "yellow",
        "pears": "green"
    }
};

if(jsObject.hasOwnProperty(myString)) {
    //myString is a key on the Object, but not its prototype.
    console.log(myString + ' is a property of jsObject');
}

If really want to search the keys(), use .indexOf()

For the way that you are doing this, the method Array.prototype.indexOf() would be more appropriate. The .indexOf() method searches through an array and returns the index of the first matching entry. You can test to see that the return value is > -1 as an indicator that there is a matching entry in the array.

var myString = "Item1";

var jsObject = {
    Item1: {
        "apples": "red",
        "oranges": "orange",
    },
    Item2: {
        "bananas": "yellow",
        "pears": "green"
    }
};

if(Object.keys(jsObject).indexOf(myString)>-1) {
    //myString is a property.
    console.log(myString + ' is a property of jsObject');
}
like image 43
Makyen Avatar answered Nov 11 '22 17:11

Makyen


You can do this a couple of ways:

for (var key in jsObject) {
  if (myString == key) {
  }
}

or

Object.keys(jsObject).forEach(function(key) { //loop through keys array
  if (myString == key) {
  }
});

or

for (var x = 0; x < Object.keys(jsObject).length; x++)
{
  if (myString == Object.keys(jsObject)[x])
  {
    // Do stuff
  }
}

Given the use of the original object, you could simply skip the loop ...

if (typeof jsObject[myString] !== "undefined") {
}
like image 3
rfornal Avatar answered Nov 11 '22 17:11

rfornal