1

I am trying to write a function that will retrieve a value by key, including searching in nested objects.

Here is as far as I got:

function getByKey (obj, key) {
   if(obj.hasOwnProperty(key)){
         return obj[key];
   }else{
      for(var prop in obj){
          if(typeof prop  == "object" && prop !== null){
             if(prop.hasOwnProperty(key)){
               return prop[key];
             }else{
               return iterate(prop, key);
             }
          }
     }
  }

}

If someone have this function ready and working or can fix my it will be great. If someone knows Underscore function that can do this it will be great.

4
  • typeof needs no brackets, null is an object, iterate is missing. Commented Sep 21, 2016 at 13:57
  • Are you trying to get all values that have this same key? If so call recursively function that goes deep in objects. Commented Sep 21, 2016 at 13:59
  • @Leolian - that is what I am trying to do. Commented Sep 21, 2016 at 14:00
  • Nested objects might hold same keys for different values so which one are you interested in such as the first one, last one or all? Commented Sep 21, 2016 at 14:32

4 Answers 4

3

You could use an iterative and recursive style to search for the property of an object.

function getByKey(obj, key) {
    function iter(o) {
        if (o !== null && typeof o === 'object') {
            if (key in o) {
                value = o[key];
                return true;
            }
            return Object.keys(o).some(function (k) {
                return iter(o[k]);
            });
        }
    }

    var value;
    iter(obj);
    return value;
}

var o = { a: 1, b: { c: 3, d: 4, e: { f: 5, g: 6 } } }

console.log(getByKey(o, 'f')); // 5
console.log(getByKey(o, 'b')); // { c: ... }
console.log(getByKey(o, 'd')); // 4
console.log(getByKey(o, 'q')); // undefined
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

Comments

2

Try the following: https://jsfiddle.net/0yqu339t/4/

function getByKey(obj, key) {
      if (obj.hasOwnProperty(key)) {
        return obj[key];
      } else {
        for (var prop in obj) {
          if (typeof(obj[prop]) === "object") {
            return getByKey(obj[prop], key);
          }
        }
      }
    }


    var o = {
      a: 1,
      b: {
        c: 3,
        d: 4,
        e: {
          f: 5,
          g: 6
        }
      }
    }
    console.log(getByKey(o, 'f'));
    console.log(getByKey(o, 'b'));
    console.log(getByKey(o, 'd'));

Comments

1

The problem is you're passing a reference to the key only to the iteration function, but never reference the original object that was passed to it. You need to use obj[prop], as follows:

function getByKey (obj, key) 
{
    if( obj.hasOwnProperty(key) )
    {
        return obj[key];
    }
    else
    {
        for(var prop in obj)
        {
            if( typeof obj[prop] == "object")
            {
                if(obj[prop].hasOwnProperty(key))
                {
                    return obj[prop][key];
                }
                else
                {
                  return getByKey(obj[prop], key);
                }
            }
        }
    }
};

jsFiddle Demo

2 Comments

Trying and posting the result. thank's for the edit, it was a long day (:
It gets error id you don't check that the object is not null, either then that, works great,
1

For recursively you can try ( with little help from JQuery )

var haystack = $.map(obj, function(value, index) {
    return [value];
});
var values = []; //or {} depending your situation
var getValues = function( needle, haystack, array ){
    if( haystack[key]) !== 'undefined' ){
      array.push(haystack[key]);
    }else{
      for( var i = 0; i < haystack.length; i++ ){
            getValues( needle , haystack[i], array );
      }
    }
}
getValues( 'key', haystack, values );
console.log(values);  //should be an array [ value1, value2, value3, value4, ... ]
//With all values that have this same searched key

I hope this helps

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.