嵌套复杂JSON中的搜索键

时间:2016-08-06 14:08:40

标签: javascript jquery json

我必须通过JavaScript或jQuery搜索嵌套JSON中的密钥。在我的JSON对象中,所有键都是唯一的。我自己尝试了一些解决方案,但它们没有用。 这是我的代码:

print_r($_POST);

如何在给定对象中搜索特定键?

如果我通过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", ...] } }],... } ,则应该返回lookup(json, "type a"),或者如果我搜索"Pumpkin",则应该返回"White Flower 2"

这是我的尝试,这是行不通的:

["Bogan 1", "Bogan 2", ...]

要查找对象的类型,请使用以下代码:

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;
    } 
}

6 个答案:

答案 0 :(得分:2)

你比你想象的更近 - 从return null;移出for (key in obj)是最重要的事情;否则,只要对象中的第一个键不匹配,您就会放弃。只有在搜索完所有键后才放弃。

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。没有“JSON对象”这样的东西。如果它不是字符串,那么它不是JSON。您正在搜索JavaScript对象。

答案 1 :(得分:1)

您可以使用以下代码 -

 var yourData = $.map(obj, function(el) { return el });  
    //Searching for the key in stored data
            var result = $.grep(yourData, function (e) {
                return e.key == your_search_key;
            });

它会返回所有匹配项,您可以访问result[0] 希望这会对你有所帮助。

答案 2 :(得分:1)

这是一个递归版本,用ES6编写(但要转换为ES5,您只需要用正常的箭头函数替换箭头函数,并用const替换var s。) p>

// We could have just returned null if there was no match, but then it wouldn't work if your data contained null.
const notFound = {};

function lookup(obj, search) {

  // Iterate over the object.
  Object.keys(obj).forEach(key => {

    // If we found the key we're looking for, return the matching value.
    if (key === search) {
      return obj[key];

    // If we've got a nested object, recursively call lookup on it.
    // If this object has the key we're looking for, return the matching value.
    } else if (obj[key].constructor === {}.constructor) {
      const result = lookup(obj[key], search);
      if (result !== notFound) return result;
    }

    // Otherwise just go onto the next iteration.

  });

  // If iterating didn't return any matching keys, return notFound.
  return notFound;

}

答案 3 :(得分:1)

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);

答案 4 :(得分:0)

不优雅,但有趣且高效!

&#13;
&#13;
function get(data, key) {
  let str = JSON.stringify(data);
  let r = new RegExp(`${key}":"([^"]{1,})"`);
  
  let res = r.exec(str);
  
  return res && res.pop() || null;
}

var data = {
  "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"
          ]
        }
      }
    }
  ]
};
console.log('result', get(data, "type a"));
&#13;
&#13;
&#13;

答案 5 :(得分:0)

编辑:问题是要求使用 plain js jquery ,我的答案使用了另一个库。但是,我仍然将其作为参考,因为它是对实际问题的一种干净的解决方案。


原始答案

我们使用object-scan满足所有数据处理需求。一旦掌握了如何使用它,它就会很强大,并且可以轻松维护代码。这是您回答问题的方式

const objectScan = require('object-scan');

const lookup = (data, term) => objectScan(['**'], {
  abort: true,
  rtn: 'value',
  filterFn: ({ property }) => property === term
})(data);

const 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"] } } }] };

console.log(lookup(json, "type a"));
// => Pumpkin
console.log(lookup(json, "White Flower 2"));
// => [ 'Bogan 1', 'Bogan 2' ]