Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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";
    }
}
like image 492
Laxmikant Avatar asked Dec 24 '22 03:12

Laxmikant


2 Answers

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 (var key in obj) {
    var value = obj[key];

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

    if (typeof(value) === "object" && !Array.isArray(value)) {
      var y = lookup(value, k);
      if (y && y[0] == k) return y;
    }
    if (Array.isArray(value)) {
      // 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.

like image 177
Paul Roub Avatar answered Feb 16 '23 00:02

Paul Roub


function lookup(obj, k) {
  if(typeof(obj) != 'object') {
    return null;
  }
  var result = null;
  if(obj.hasOwnProperty(k)) {
    return obj[k];
  } else {
    for(var o in obj) {
      result = lookup(obj[o], k);
      if(result == null) continue;
      else break;
    }
  }
  return result;
}
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"] 
        }
      }
    }
  ]
}
var rs = lookup(json,'type a');
console.log(rs);
like image 20
Shenyun Avatar answered Feb 15 '23 22:02

Shenyun