Laxmikant Laxmikant - 4 months ago 14
Javascript Question

Search key in nested complex JSON

I have to search for a key in nested JSON by JavaScript or by jQuery. In my JSON object all the keys are unique. I tried some solutions myself but they did not work.
Here is my code:

json = {
"app": [{
"Garden": {
"Flowers": {
"Red flower": "Rose",
"White Flower": "Jasmine",
"Yellow Flower": "Marigold"
}
},
"Fruits": {
"Yellow fruit 1": "Mango",
"Green fruit 2": "Guava",
"White Flower 3": "groovy"
},
"Trees": {
"label": {
"Yellow fruit 2": [{"type a":"Pumpkin", "type b": "Banana",..}],
"White Flower 2": ["Bogan 1", "Bogan 2", ...]
}
}],...
}


How can I search for a specific key in given object?

If I pass
lookup(json, "type a")
it should return
"Pumpkin"
, OR If I search for
"White Flower 2"
it should return
["Bogan 1", "Bogan 2", ...]


Here is my try, which is not working:

function lookup(obj, k){
for (key in obj){
value = obj[key];
if (k == key) return [k, value];
if (type(value) == "Object"){
var y = lookup(value, k);
if (y && y[0]== k)return y;
}
if(type(value) == "Array"){
for (i in value)
{
var x = lookup(value[i], k);
if (x && x[0]== k)return x;
}
}
console.log(key, value);
return null;
}
}


To find the type of the object, I'm using this code:

function type(object){
var stringConstructor = "test".constructor;
var arrayConstructor = [].constructor;
var objectConstructor = {}.constructor;

if (object === null) {
return "null";
}
else if (object === undefined) {
return "undefined";
}
else if (object.constructor === stringConstructor) {
return "String";
}
else if (object.constructor === arrayConstructor) {
return "Array";
}
else if (object.constructor === objectConstructor) {
return "Object";
}
else {
return "null";
}
}

Answer

You're closer than you think - moving return null; out of for (key in obj) is the main thing; otherwise, you're giving up as soon as the first key in the object doesn't match. Only give up after searching all the keys.

function lookup(obj, k) {
  for (key in obj) {

    value = obj[key];
    if (k == key) return [k, value];

    if (type(value) == "Object") {
      var y = lookup(value, k);
      if (y && y[0] == k) return y;
    }
    if (type(value) == "Array") {
      // for..in doesn't work the way you want on arrays in some browsers
      //
      for (var i = 0; i < value.length; ++i) {
        var x = lookup(value[i], k);
        if (x && x[0] == k) return x;
      }
    }
  }

  return null;
}

var json = {
  "app": [{
    "Garden": {
      "Flowers": {
        "Red flower": "Rose",
        "White Flower": "Jasmine",
        "Yellow Flower": "Marigold"
      }
    },
    "Fruits": {
      "Yellow fruit 1": "Mango",
      "Green fruit 2": "Guava",
      "White Flower 3": "groovy"
    },
    "Trees": {
      "label": {
        "Yellow fruit 2": [{
          "type a": "Pumpkin",
          "type b": "Banana"
        }],
        "White Flower 2": ["Bogan 1", "Bogan 2"]
      }
    }
  }]
}

function type(object) {
  var stringConstructor = "test".constructor;
  var arrayConstructor = [].constructor;
  var objectConstructor = {}.constructor;

  if (object === null) {
    return "null";
  } else if (object === undefined) {
    return "undefined";
  } else if (object.constructor === stringConstructor) {
    return "String";
  } else if (object.constructor === arrayConstructor) {
    return "Array";
  } else if (object.constructor === objectConstructor) {
    return "Object";
  } else {
    return "null";
  }
}

console.log(lookup(json, 'type a'));
console.log( lookup(json, 'White Flower 2') );

p.s. There is no such thing as a "JSON object". If it's not a string, it's not JSON. You're searching through JavaScript objects.