解析完整的JSON并搜索匹配值的键

3

我希望能够在JavaScript中遍历整个JSON并找到从特定键开始的值。 假设这是我的JSON数据:

var data = {
  "array": [
    1,
    2,
    3
  ],
  "boolean": true,
  "null": null,
  "number": 123,
  "object": {
    "a": "b",
    "abc":{
      "mohit_ab": {
        "id1":"i am id 1",
        "abcd":{
          "a" :"b",
          "c":"d"
        },
        "who" : "who are you",
        "id2":"i am id 2"
      },
      "mohit_231abcd": {
        "id1":"i am id 3",
        "identity" : "i am real mohit",
        "id2":"i am id 4"
      }
    },
    "hji":{
      "mohit_adss231": {
        "id1":"i am id 5",
        "identity" : "i am mohit in real",
        "id2":"i am id 6"
      },
      "mohit": {
        "id7":"i am id 7",
        "identity" : "i am mohit and you?",
        "id8":"i am id 8"
      }
    },
    "c": "d",
    "e": "f"
  },
  "string": "Hello World"
};

我希望能在JavaScript中解析完整的JSON,并获取键以“mohit”开头的值。例如,上面输入的输出为:
valueableData:{
  "mohit_ab": {
        "id1":"i am id 1",
        "abcd":{
          "a" :"b",
          "c":"d"
        },
        "who" : "who are you",
        "id2":"i am id 2"
      },
      "mohit_231abcd": {
        "id1":"i am id 3",
        "identity" : "i am real mohit",
        "id2":"i am id 4"
      },
      "mohit_adss231": {
        "id1":"i am id 5",
        "identity" : "i am mohit in real",
        "id2":"i am id 6"
      },
      "mohit": {
        "id7":"i am id 7",
        "identity" : "i am mohit and you?",
        "id8":"i am id 8"
      }
}

请为我提供实现此目标的简单方法。
3个回答

2

您自己的答案中使用的递归方法是一个很好的通用解决方案,始终是可行的。
但是它完全遍历了源对象,因此在存在大量嵌套子对象的情况下,可能会影响性能。

通过下面的解决方案,整个源对象也被完全遍历,但工作是由JS内部完成的,这更快。
此外,代码更简洁易读。

var data = {
  "array": [
    1,
    2,
    3
  ],
  "boolean": true,
  "null": null,
  "number": 123,
  "object": {
    "a": "b",
    "abc":{
      "mohit_ab": {
        "id1":"i am id 1",
        "abcd":{
          "a" :"b",
          "c":"d"
        },
        "who" : "who are you",
        "id2":"i am id 2"
      },
      "mohit_231abcd": {
        "id1":"i am id 3",
        "identity" : "i am real mohit",
        "id2":"i am id 4"
      }
    },
    "hji":{
      "mohit_adss231": {
        "id1":"i am id 5",
        "identity" : "i am mohit in real",
        "id2":"i am id 6"
      },
      "mohit": {
        "id7":"i am id 7",
        "identity" : "i am mohit and you?",
        "id8":"i am id 8"
      }
    },
    "c": "d",
    "e": "f"
  },
  "string": "Hello World"
};

var valuableData = {};
JSON.parse(JSON.stringify(data), function(key, value) {
  if (key.substr(0, 5) == 'mohit') {
    valuableData[key] = value;
  }
  return value;
});

document.write('ValuableData:');
for (var key in valuableData) {
  document.write('<br />' + key + ': ' + JSON.stringify(valuableData[key]));
}

这是要翻译的内容,附带解释注释:

var valuableData = {};
// use JSON.parse, not to get its result but only to benefit of its "reviver" function
JSON.parse(JSON.stringify(data), function(key, value) {
  // when encoutering one of the keys we're looking for, populate our own result
  if (key.substr(0, 5) == 'mohit') {
    valuableData[key] = value;
  }
  // in any case, don't break the normal generation of the JSON.parse result
  // (or the keys we select above would have been left empty!)
  return value;
});

嘿,谢谢你的评论。我对JavaScript还很陌生,你能告诉我如何在数据中进行搜索迭代以获取这些键的值吗? - Mohit Jain
@MohitJain 哦...抱歉,我本打算在回复你的评论时完成我的答案,但后来意识到我和其他回答者一样错了;没有关注到不同的层次。所以目前我的答案没有帮助!不过,我觉得这个问题真的很有趣,所以我会尽力给出一个有用的答案...但是只能在明天了,因为现在对我来说已经是凌晨5点了 :) - cFreed
没问题,请尽快尝试并在方便时回复我答案。谢谢.. :-) - Mohit Jain
从你最初的问题中,我想你认为自己已经得到了一个递归方法,但正在寻找更简洁的方法:这就是我发布第一个答案的原因,但那是错误的。实际上,我最终找到了一个(在我看来)不错的方法:请看我的编辑后的答案。关于你自己的答案,请看我的评论。 - cFreed
嗨,谢谢你的解决方案,你使用JSON.parse函数的方式似乎很有趣。我相信你的解决方案会更快。但是,有没有办法测试两种解决方案的性能呢? - Mohit Jain
显示剩余2条评论

1
我为此编写了一个函数:

var valueAbleData = {};
  this.add = function(value) {
      for (var key in value){
            if(key.indexOf("mohit") > -1){
                valueAbleData[key] =  value[key];
            }
            else if(value[key] !== null && typeof value[key] === 'object'){
                this.add(value[key]);
            }
            }
    };

如果有人能提供更好的答案,请发帖。:)


正如我在自己的回答中所述,我认为这是一个很好的方法(几乎可以将递归用于一切),但如果应用于大型源数据,则可能会有害。因此,当有其他选择时,最好考虑其他方案。这里我只注意到两点:1)除非我漏掉了什么微小的东西,否则我不理解你的this:你可能只需要function add(value); 2)使用key.indexOf('mohit') > -1也会选择诸如foobar-mohit之类的键!因此,最好使用== 0 - cFreed
针对您的两个问题的答案: 1)这只是本地系统上的演示功能,add(value)和this。在确定我的答案后,我会进行更改。 2)感谢您提供的indexOf('mohit'),我会将其更改为0。 - Mohit Jain

0
你可以利用一个for循环
var results = [];
for (var key in valueableData)
{
    if ( key.indexOf("mohit") == 0 )
      results.push(valueableData[key]);
}

results 数组将包含匹配的对象。


这种方法只能在我们的数据处于相同级别时才能奏效,但我的数据是分层的。它只会循环顶层。 - Mohit Jain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接