-2

I want to check if an "key" is present in a JS object. Is there a way of doing this? +the data can be an arbitrary subbranch within sometree

Example:

var sometree = {
    foo : {
        data : 1
    },
    foo2 : {
        data : 5
    }
}

function checkForKey(key, obj) {
    //If I do "checkForKey(5, sometree)", I want the function
    //to return "sometree.foo2.data".
}
jonathanhuo11
  • 728
  • 1
  • 6
  • 10

3 Answers3

-1

You'll need something recursive if the object can be an arbitrary depth:

    var sometree = {
        foo: {
            data: 1
        },
        foo2: {
            data: 5
        }
    }

    function checkForValue( value, json, name ) {
        var result = checkObject( value, json );
        return result ? name +'.'+ result : null;
    }

    function checkObject( value, json ) {
        var keys = Object.keys(json);
        for ( var i = 0; i < keys.length; i++ ) {
            var key = keys[i];
            if ( typeof json[key] === 'object' && json[key] !== null ) {
                var result = checkObject( value, json[key] );
                if ( result )
                    return key +'.'+ result;
            }
            else if ( json[key] === value ) {
                return key;
            }
        }
        return null;
    }

    document.write( checkForValue( 5, sometree, 'sometree' ) );
TbWill4321
  • 8,626
  • 3
  • 27
  • 25
  • Breaks if anything has `'.'` within the key. – Andrew Templeton Jan 10 '16 at 03:04
  • It doesn't break, there was no specification on how to handle a `.` in key names. It does return the expected string, and if dots need escaping that can be handled in another question. – TbWill4321 Jan 10 '16 at 03:12
  • You also don't address the fact that he can't recover the `sometree` / input variable identifier. I mean, we can argue about it, but there's shortcomings in it, and given that this is beginner question, I would imagine it's dangerous to give him code that definitely doesn't do what he wants in one aspect and probably doesn't in another... – Andrew Templeton Jan 10 '16 at 03:15
  • Fixed the issue of missing input variable name. – TbWill4321 Jan 10 '16 at 03:21
-2

Following should work:

function checkForKey(key, json) {
    var found = false;
    for(var x in json) {
        if (json.hasOwnProperty(x)) {
            if(json[x][data] == key) {
                found = key;
            }
        }
    }
    return found;
}
seahorsepip
  • 4,519
  • 1
  • 19
  • 30
  • He never sayed it was, I assumed he wanted to check the data keys inside the foo keys...Thanks for the downvote – seahorsepip Jan 10 '16 at 03:01
  • You also reference `data` herein - It's broken code and doesn't go down 2 levels into the object, I am sorry if the downvote offends you. – Andrew Templeton Jan 10 '16 at 03:07
  • Since data is the subkey of every foo in his json object...he never stated it had more levels and that it had keys besides data in the question...My code isn't broken therefore... – seahorsepip Jan 10 '16 at 03:11
  • 1
    He means it's broken because `[data]` checks the variable `data`, your code would function as `['data']` instead. – TbWill4321 Jan 10 '16 at 03:28
  • Oh I typed the quotes though but somehow they disappeared :/ Seems typing code on my phone is a bad idea. – seahorsepip Jan 10 '16 at 03:31
-2

The getDeepKeyForValue function can be implemented either in "just give me one" form or "give me all of them". You could also ask this to support complex objects, but I wrote the ones to support simple values. NOTE: because keys can have '.' in them, I return an Array of the key path and let you handle those corner cases. You also can't recover the sometree identified/variable name from within the function. This will work...:

   function getDeepKeyForValue (value, object, path) {
    var keySet = Object.keys(object || {});
    var key;
    var result;
    path = path || [];
    keySetLength = keySet.length;
    while (keySetLength--) {
        key = keySet[keySetLength];
        if (value === object[key]) {
            return path.concat(key);
        }
        result = getDeepKeyForValue(value, object[key], path.concat(key));
        if (result) {
            return result;
        }
    }
    return null;
}
Andrew Templeton
  • 1,656
  • 10
  • 13
  • Hey never stated that it was deepkey value :P So this might be overkill and only recommended when it's actually needed. This SO question is becoming kinda http://needsmorejquery.com xD – seahorsepip Jan 10 '16 at 03:09
  • Yeah, he did... As in, directly in the question, `sometree.foo2.data` is a deep path / greater than one hop into the object... – Andrew Templeton Jan 10 '16 at 03:10
  • He never stated it was a variable depth and data was a variable. So it's a single depth object with the values wrapped in a object called data. – seahorsepip Jan 10 '16 at 03:13
  • Are we reading the same question?? Read the example comments in the code, and you can clearly see he is passing in the compound object `sometree` looking for a 2-deep value... – Andrew Templeton Jan 10 '16 at 03:16
  • Yeah but you assume that 2 deep can be 3 deep or 4 deep and that data can be hello which is not stated in the question. A deep search makes only sense when the object layout is unknown but we do know that it's only 2 deep and that the second depth keys are called data. – seahorsepip Jan 10 '16 at 03:21