【问题标题】:Finding inner most keys in JSON在 JSON 中查找最内部的键
【发布时间】:2013-09-06 06:30:24
【问题描述】:

我有兴趣找到 JSON 的最里面的键。例如,如果我有以下 JSON:

{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
    "id": {
        "description": "The unique identifier for a product",
        "type": "integer"
    },
    "name": {
        "description": "Name of the product",
        "type": "string"
    },
    "price": {

        "minimum": 0,
    "type": "number",
        "exclusiveMinimum": true
    }
},
"required": ["id", "name", "price"]
}

那么输出应该有:descriptiontypedescriptiontypeminimum、typeexclusiveMinimum 作为最内层的键。

【问题讨论】:

  • 好的。你试过什么?你在哪里卡住了?
  • 另外:你想在什么语言和环境中做这件事?网页浏览器上的 JavaScript? Java(适用于 Android 或其他)? C#?
  • @T.J.Crowder 我正在寻找用 Java 编写代码

标签: json key


【解决方案1】:

远非好,但看起来可行,试试 Javascript 示例http://jsfiddle.net/3UMx5/2/

PS:对不起我的英语

用法

 var data = {
     "$schema": "http://json-schema.org/draft-04/schema#",
     "title": "Product",
     "description": "A product from Acme's catalog",
     "type": "object",
     "todo": {
         "level1": {
             "level2": {
                 "level3": {
                     "key": "here"
                 }
             }
         }
     },
     "properties": {
         "id": {
             "description": "The unique identifier for a product",
             "type": "integer"
         },
         "name": {
             "description": "Name of the product",
             "type": "dwq"
         },
         "price": {
             "minimum": 0,
             "type": "number",
             "exclusiveMinimum": true
         }
     },
     "required": ["id", "name", "price"]
 }

 searchInnermost(data);

Javascript

function searchInnermost(data){
    //convert json to string
    var jsonString = JSON.stringify(data);
    //split json string into chars
    var chars      = jsonString.split('');

    var mostInnerChars = getInnerMostChars(chars);
    var mostInnerJson  = restoreJsonFromChars(mostInnerChars);

    var keys = getKeysOnly(mostInnerJson)
    return keys;
}

function getInnerMostChars(chars){
    var level      = 0;
    var maxLevel   = level;
    var items      = [];

    //loop throught each char
    for(var i = 0; i < chars.length; i++){
        //TODO more accurate identifier needed, if { -> deeper level, level increased
        if(chars[i] == '{'){
            level++;
            if(level > maxLevel){
                maxLevel = level;
            }
        }        

        //store each char in levels array
        if(!items[level]){
            items[level] = [];
        }

        items[level].push(chars[i]);

        //if } -> level reduced
        if(chars[i] == '}'){
            level--;
        }
    }

    return items[maxLevel];
}
//restore json string
function restoreJsonFromChars(chars){
    var restored = chars.join('').replace(/\}\{/g, '},{');
    restored = '[' + restored + ']';
    return JSON.parse(restored);
}
//get json keys
function getKeysOnly(json){
    var keysOnly = [];
    for(var i = 0; i < json.length; i++){
        for(var key in json[i]){
            keysOnly.push(key);
        }
    }

    return keysOnly;
}

【讨论】:

  • 非常感谢您的及时回复。我忘了提到我不太了解 javascript,我打算用 Java 编写代码。
【解决方案2】:

更简单的方法:
第一个函数查找所有属性及其级别

function findAllProperties(obj)
{
   var retVal = [];
   (function findProperty(obj, depth)
   {
       for (var prop in obj)
       {
           if (obj[prop] instanceof Object)
           {
              findProperty(obj[prop], depth + 1); 
           }
           else
           {
              retVal.push({"name" : prop, "depth" : depth}); 
           }
       }
   })(obj, 0);
   return retVal;
} 

第二个函数查找最大级别的属性

function siftInnerMost(items)
{
    var maxDepth = 0, retVal = [];
    for (var i in items)
    {
        if (items[i].depth == maxDepth)
        {
           retVal.push(items[i].name);
        }
        else if (items[i].depth > maxDepth)
        {
           maxDepth = items[i].depth;
           retVal = [items[i].name];
        }
    }
    return retVal;
}  

现在你可以找到inner most

var inners = findAllProperties(data);
var innerMost = siftInnerMost(inners);  

JSFiddle DEMO

Java 解决方案与Json-Simple lib

public class InnerMostFinder 
{
   private List<Pair> inners = new ArrayList<Pair>();

    private static class Pair
    {
       int level;
       String property;

       public Pair(int level, String property) 
       {
          this.level = level;
         this.property = property;
       }
    }

    private void findAllProperties(final JSONObject obj, final int level)
    {
       for (Object key : obj.keySet())
       {
          Object innerObj = obj.get(key);
          if (innerObj instanceof JSONObject)
          {
             findAllProperties((JSONObject) innerObj, level + 1); 

          }
          else
          {
              inners.add(new Pair(level, (String) key)); 
          }
       }
    }

    public List<String> getInnerMost(final JSONObject obj)
    {
       final List<String> retVal = new ArrayList<String>();
       int maxLevel = 0;
       findAllProperties(obj, maxLevel);
       for (final Pair pair : inners)
       {
          if (pair.level == maxLevel)
          {
             retVal.add(pair.property);
          }
          else if (pair.level > maxLevel)
          {
             maxLevel = pair.level;
             retVal.clear();
             retVal.add(pair.property);
          }
       }
       return retVal;
    }
}  

用法

   JSONObject obj = (JSONObject) new JSONParser()
      .parse(new FileReader(new File("D:/test.json")));
   System.out.println(new InnerMostFinder().getInnerMost(obj));

【讨论】:

  • 非常感谢您的及时回复。我忘了提到我不太了解 javascript,我打算用 Java 编写代码。
  • @AkshayAmbekar 在 JavaScript 上做起来更简单
  • 同意@llya,但我有严格的限制。你能用Java推荐一些东西吗?
  • @AkshayAmbekar Java 解决方案已添加
猜你喜欢
  • 2019-01-07
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 2021-09-05
  • 1970-01-01
  • 2019-12-24
  • 1970-01-01
相关资源
最近更新 更多