Eusthace
Eusthace

Reputation: 3861

If key of a object contains a word

I've got a object like this:

{"status":200, 
"success":true, 
"result": [ {"Description":"", "Year":"", "Price/STK":"", "Main Cat":"Fruits"} ]
}

I have distinct lists I need to use, and the Price key can be: Price/STK, Price/Box, Price/Btl or Price.

I know I can get the value using, for example, data.result['Price/STK'], but I don't want to check every key, I'd like to search for the price and just use.

How would I determine if a word ('Price*', for example) is part of a key and get that value?

Upvotes: 2

Views: 5261

Answers (4)

Software Engineer
Software Engineer

Reputation: 16130

You could solve this problem easily using lodash (or underscore)

_.findKey(obj, function(key) { return _.startsWith(key, 'Price')})

This finds the first key that starts with price.

Upvotes: 3

RobG
RobG

Reputation: 147413

You can get the property names of an object using Object.keys, and then use indexOf to search for a value, but it does an exact match and doesn't take a regular expression as an argument.

So you have to loop over all the property names until you find the one you want. There are built–in iterators to help:

var obj = {"status":200, 
  "success":true, 
  "result": [ {"Description":"desc", 
               "Year":"yr", 
               "Price/STK":"price/stk",
               "Main   Cat":"Fruits"}
            ]
};

function getValueLike(obj, prop){
  var re = new RegExp('^' + prop);
  var value;
  Object.keys(obj).some(function(prop) {
    if (re.test(prop)) {
      value = obj[prop];
      return true;
    }
  });
  return value;
}

document.write(getValueLike(obj.result[0], 'Price')); // price/stk

A version that uses indexOf on the property name might be faster and is a little less code:

function getValueLike(obj, prop){
  var value;
  Object.keys(obj).some(function(key) {
    if (key.indexOf(prop) == 0) {
      value = obj[key];
      return true;
    }
  });
  return value;
}

which can be reduced to:

function getValueLike(obj, prop, value){
  Object.keys(obj).some(function(key) {return key.indexOf(prop) == 0 && ((value = obj[key]) || true)});
  return value;
}

which also allows a default value to be passed to value, but it's a little too obfuscated for me.

Using an arrow function:

function getValueLike(obj, prop, value){
  Object.keys(obj).some(key => key.indexOf(prop) == 0 && ((value = obj[key]) || true));
  return value;
}

Upvotes: 2

Travis J
Travis J

Reputation: 82287

Filter the set of keys on the result array's object for "Price", and then return the value associated with that. I made a function for it as an example.

function selectPrice(obj){
  return obj.result[0][
      Object.keys(obj.result[0]).filter(function(el){ 
          return el.indexOf("Price") > -1 
      })[0]
  ]
}

var data = {"status":200, 
"success":true, 
"result": [ {"Description":"", "Year":"", "Price/STK":"6", "Main Cat":"Fruits"} ]
};

document.write(selectPrice(data));

Upvotes: 0

adeneo
adeneo

Reputation: 318232

There's no built in way to do this, you have to iterate and check each key.

You could just create a convenient function :

function matchKey(objectToSearch, keyToFind) {
    for (var k in objectToSearch) {
        if ( k.toLowerCase().indexOf(keyToFind.toLowerCase()) !== -1) 
            return objectToSearch[k];
    }
    return null;
}

matchKey({year : 2015, "Price/STK" : "value"}, "price"); // returns "value"

FIDDLE

Upvotes: 7

Related Questions