Javascript 使用递归函数遍历 JSON 字符串到内部级别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10459917/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 01:24:30  来源:igfitidea点击:

traversing through JSON string to inner levels using recursive function

javascriptarraysjsonobject

提问by user1371896

I have a JSON input which can go to any number of levels.

我有一个可以进入任意级别的 JSON 输入。

I'm giving an input sample of

我给出了一个输入样本

var d=getEntities( {"Categories": 
{
"Facets": 
    [
    {
    "count": 1,
    "entity": "Company",
    "Company": 
            [
            {

            "entity": "Ford Motor Co",

            "Ford_Motor_Co": 
                [
                    {
                    "count": 1,
                    "entity": "Ford"
                    }
                ]
            }
            ]
    },
        {
            "count": 4,
            "entity": "Country",
              "Country": [
                    {

                        "entity": "Germany",
                         "Germany": [
                                {
                                    "count": 1,
                                    "entity": "Germany"
                                }
                          ],
                        "currency": "Euro (EUR)"
                    },
                    {

                         "entity": "Italy",
                        "Italy": [
                                {
                                     "count": 1,
                                     "entity": "Italy"
                                }
                          ],
                        "currency": "Euro (EUR)"
                    },
                    {

                        "entity": "Japan",
                          "Japan": [
                             {
                                    "count": 1,
                                    "entity": "Japan"
                             }
                          ],
                        "currency": "Yen (JPY)"
                    },
                    {

                        "entity": "South Korea",
                          "South_Korea": [
                              {
                                    "count": 1,
                                    "entity": "South Korea"
                                }
                          ],
                      "currency": "Won (KRW)"
                    }
              ]
        },
        {"count": 5,
              "entity": "Persons",
              "Persons": [
                    {
                         "count": 2,
                        "entity": "Dodge"
                    },
                    {
                        "count": 1,
                        "entity": "Dodge Avenger"
                    },
                    {
                        "count": 1,
                        "entity": "Major League"
                    },
                    {
                        "count": 1,
                        "entity": "Sterling Heights"
                    }
              ]
        }
  ]

}});

I want to add the key value "Entity" in all levels to an array using recursion,

我想使用递归将所有级别的键值“实体”​​添加到数组中,

I'm able to collect the data from first level using the string

我可以使用字符串从第一级收集数据

<html>
<head>
<script src="jquery.js" type="text/javascript"></script>
<script type="text/javascript" src="dataDumper.js"></script>


<script type="text/javascript">

var testJSON = {"Categories": 
{
"Facets": 
    [
    {
    "count": 1,
    "entity": "Company",
    "Company": 
            [
            {

            "entity": "Ford Motor Co",

            "Ford_Motor_Co": 
                [
                    {
                    "count": 1,
                    "entity": "Ford"
                    }
                ]
            }
            ]
    },
        {
            "count": 4,
            "entity": "Country",
              "Country": [
                    {

                        "entity": "Germany",
                         "Germany": [
                                {
                                    "count": 1,
                                    "entity": "Germany"
                                }
                          ],
                        "currency": "Euro (EUR)"
                    },
                    {

                         "entity": "Italy",
                        "Italy": [
                                {
                                     "count": 1,
                                     "entity": "Italy"
                                }
                          ],
                        "currency": "Euro (EUR)"
                    },
                    {

                        "entity": "Japan",
                          "Japan": [
                             {
                                    "count": 1,
                                    "entity": "Japan"
                             }
                          ],
                        "currency": "Yen (JPY)"
                    },
                    {

                        "entity": "South Korea",
                          "South_Korea": [
                              {
                                    "count": 1,
                                    "entity": "South Korea"
                                }
                          ],
                      "currency": "Won (KRW)"
                    }
              ]
        },
        {"count": 5,
              "entity": "Persons",
              "Persons": [
                    {
                         "count": 2,
                        "entity": "Dodge"
                    },
                    {
                        "count": 1,
                        "entity": "Dodge Avenger"
                    },
                    {
                        "count": 1,
                        "entity": "Major League"
                    },
                    {
                        "count": 1,
                        "entity": "Sterling Heights"
                    }
              ]
        }
  ]

}};

function scan(obj)
{
    var k;
    if (obj.hasOwnProperty('entity')) {



        for (k in obj){
           if (obj.hasOwnProperty(k)){


                scan( obj[k] );  


            }                
          }
    } 


    else{
        if(k=='entity')
        {
        alert(obj.entity);
   }
    }


};

scan(testJSON);



</script>
</head>

<body>

</body>

</html>

How do I get in to the inner levels for JSON string using recursive functions?

如何使用递归函数进入 JSON 字符串的内部级别?

回答by El Ronnoco

I have made a jsfiddlewhich traverses every object,array and value in the JS object like so...

我制作了一个jsfiddle,它遍历 JS 对象中的每个对象、数组和值,就像这样......

function scan(obj) {
    var k;
    if (obj instanceof Object) {
        for (k in obj){
            if (obj.hasOwnProperty(k)){
                //recursive call to scan property
                scan( obj[k] );  
            }                
        }
    } else {
        //obj is not an instance of Object so obj here is a value
    };

};

I get no recursion error (in Chrome). Can you use this to do what you want?

我没有得到递归错误(在 Chrome 中)。你能用它来做你想做的事吗?

If you need to test if an object is an array use if (obj instanceof Array)

如果您需要测试对象是否是数组,请使用 if (obj instanceof Array)

To test if an object has an "entity" property use if (obj.hasOwnProperty('entity'))

要测试对象是否具有“实体”属性,请使用 if (obj.hasOwnProperty('entity'))

To add (or modify an existing) "entity" property use obj.entity = valueor obj['entity'] = value

添加(或修改现有)“实体”属性使用obj.entity = valueobj['entity'] = value

回答by Florian Margaine

(function recur( obj ) {
    Object.keys( obj ).forEach( function( prop ) {
        // Check if the property is an object
        if ( ({}).toString.apply( prop ) === '[object Object]' ) {
            // If it is, recall this function
            recur( prop );
        }
    } );
} () );

I haven't added your logic, but you get the idea of how to recursively traverse your object.

我没有添加你的逻辑,但你知道如何递归遍历你的对象。

回答by Sam Whillance

Say I have a structure like the following:

假设我有如下结构:

var aObject = {
    items: [],
    children: {}
}

Children is an associative array that contains more aObjects. So it could look like this:

Children 是一个包含更多 aObject 的关联数组。所以它看起来像这样:

var aObject = {
    items: [],
    children: {
        "subgroup1": {
            items: [],
            children: {}
        },
        "subgroup2": {
            items: [],
            children: {}
        }
    }
}

I have an item that contains an array of subgroups:

我有一个包含子组数组的项目:

["subgroup1", "subgroup1a"]

Each subgroup is a 'location'. The item needs to be placed at:

每个子组都是一个“位置”。该项目需要放置在:

aObject.children[array[0]].children[array[1]].items

At each level, we have to check if children[array[i]] exists, and if not, create it. You can't simply write aObject.children[array[0]].children[array[1]].items.push(item) because children[array[0]] might not already exist and we will get an error.

在每个级别,我们都必须检查 children[array[i]] 是否存在,如果不存在,则创建它。你不能简单地写 aObject.children[array[0]].children[array[1]].items.push(item) 因为 children[array[0]] 可能不存在,我们会得到一个错误。

This can be solved using recursion! (AngularJS)

这可以使用递归解决!(AngularJS)

function recursive(aLevel, aItem, aArray, aIndex){
    var lLevel = aLevel;

    // If we have reached the end of the array
    if (aIndex === aArray.length){
        // Insert
        aLevel.items.push(aItem);
    } else {

        // If the subgroup doesn't exist, create it
        if (typeof aLevel.children[aArray[aIndex]] === 'undefined'){
            aLevel.children[aArray[aIndex]] = {
              items: [],
              children: {}
            };
        }

        // Move into
        recursive(aLevel.children[aArray[aIndex]], aItem, aArray, aIndex+1);
    }
}

aObject = {
    items: [],
    children: {},
}

angular.forEach(items, function(item, i){
    var location = item.location;

    if (location.length == 0){
        aObject.items.push(item);
    } else {
        recursive(aObject, item, location, 0);
    }
});

The final aObject would look like this:

最终的 aObject 将如下所示:

var aObject = {
     items: [],
     children: {
        "subgroup1": {
            items: [],
            children: {
                "subgroup1a": {
                    items: [item],
                    children: {}
                }
            }
        },
        "subgroup2": {
            items: [],
            children: {}
        }
    }
}

回答by James Harrington

Here is a function that i use often. It's easily modifiable to do many recursive tasks. For example if you add a bail flag you can quickly get the stack or add a callback function that makes it even more general. Anyway that's my 2 cents

这是我经常使用的功能。很容易修改来执行许多递归任务。例如,如果您添加一个保释标志,您可以快速获取堆栈或添加一个回调函数,使其更加通用。无论如何,这是我的 2 美分

var recursiveObjMap = (function(){
  var stack = [];
  var result = [];
  // var bail = false;
  return function map(data, key){
    if (!$.isArray(data) && !$.isPlainObject(data) ) { 
      result.push(data);
      return false 
    }

    $.each(data, function(i, v){
      if (key) stack.push(key);
      map(v, i);
      stack.pop();
    });
    return result;
  };
})();

recursiveObjMap({a:'b',c:{d:{e:"f"}}}) // ['b', 'f']