Zach Starnes
Zach Starnes

Reputation: 3198

Get object key based on value inside that object

I am trying to get the key that is associated with a certain value. If I use this:

function findKpiAttrName (obj, value) {
  _.each(obj, function (v, k) {
    if (v.hasOwnProperty('name') && v.name === value) { return k }
  });
}

var attrKey = findKpiAttrName(obj, 'KPI Name');

If I console.log(attrKey) it returns undefined but I know it is finding something because if I console.log(k) inside the above method it prints it just fine. Is there something wrong with scope that I am missing? I am using ES5 by the way.

Any help with be great! Thanks!

Upvotes: 2

Views: 120

Answers (4)

Akrion
Akrion

Reputation: 18515

You could also one line this via Object.entries and Array.find and no lodash:

let obj = { name: 'KPI Name', value: 42 }

let fn = (o, i) => (Object.entries(o).find(([k,v]) => v === i) || [])[0]

console.log(fn(obj, 'KPI Name'))  // name
console.log(fn(obj, 42))          // value
console.log(fn(obj, null))        // undefined

With lodash and ES5 compatibility just use _.findKey like this:

let obj = { name: 'KPI Name', value: 42 }

let getKeyByValue = (obj, value) => _.findKey(obj, x => x === value)

console.log(getKeyByValue(obj, 'KPI Name'))  // name
console.log(getKeyByValue(obj, 42))          // value
console.log(getKeyByValue(obj, null))        // undefined
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Upvotes: 0

exside
exside

Reputation: 3884

How about this? No lodash neaded for this =)

function findKpiAttrName(object, value) {
    return Object.keys(object).filter(function(key) {
        return object[key] === value;
    }).pop();
};

console.log(findKpiAttrName({
    name: 'KPI Name',
    value: 42
}, 'KPI Name'));

I do like @Dementic concise solution above, but .find() won't work in IE9 if that is still a concern... this solution should (I think =D, maybe...it's IE after all)

Upvotes: 0

Thomas Bui
Thomas Bui

Reputation: 198

Unfortunately, I don't understand why the return statement doesn't work. However, I can suggest the way that I'd do this question:

function findKpiAttrName (obj, value) {
  let keys = Object.keys(obj);
  return keys.find(function (key) {
    if (obj[key] === value) return true;
  })
}

I hope that helps.

Upvotes: 1

davidbuzatto
davidbuzatto

Reputation: 9424

Maybe something like this:

function findKpiAttrName (obj, value) {
  let d = null;
  _.each(obj, function (v, k) {
    if (v.hasOwnProperty('name') && v.name === value) { d = k; return false; }
  });
  return d;
}

Or maybe this is even better:

function findKpiAttrName(obj, value) {
  for (let [k, v] of Object.entries(obj)) {
    if ( v.hasOwnProperty('name') && v.name === value) {
      return k;
    }
  }
}

Upvotes: 0

Related Questions