Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript中的递归以在重JSON中搜索_Javascript_Json_Algorithm_Recursion_Bigdata - Fatal编程技术网

JavaScript中的递归以在重JSON中搜索

JavaScript中的递归以在重JSON中搜索,javascript,json,algorithm,recursion,bigdata,Javascript,Json,Algorithm,Recursion,Bigdata,我面临一个算法概念问题。使用JavaScript语言,我有一个大约11000行的重JSON对象,这是HTML文件转换的结果。JSON的结构类似于DOM的结构,这意味着一个对象可以有一个属性子对象,一个由其他类似对象组成的数据结构。目标是在JSON中搜索并提取具有该属性的对象的属性itemprop的信息。itemprop属性位于前面提到的一些对象所具有的attributes属性中,而Object位于attributes属性中 对象结构 { type: 'x', tagName: 'y',

我面临一个算法概念问题。使用JavaScript语言,我有一个大约11000行的重JSON对象,这是HTML文件转换的结果。JSON的结构类似于DOM的结构,这意味着一个对象可以有一个属性子对象,一个由其他类似对象组成的数据结构。目标是在JSON中搜索并提取具有该属性的对象的属性itemprop的信息。itemprop属性位于前面提到的一些对象所具有的attributes属性中,而Object位于attributes属性中

对象结构

{ type: 'x',
  tagName: 'y',
  attributes: { "itemprop" : "valueWanted" },
  children:
   [ Object, Object, Object] 
}
{
 "type": "",
  "tagName": "",
  "attributes": {
  "itemprop": "wantedValue"
   },
  "children": [{
      "type": "",
      "content": ""
      }
    ]
  },
 {
  "type": "",
  "content": ""
  }]
  },         
   {
  "type": "",
  "tagName": "",
  "attributes": {},
  "children": [
  {
   "type": "",
    "content": "here"
   }
  ]
我想到了一个递归算法来解决这个问题。不幸的是,我不熟悉递归,下一个代码不起作用

递归算法

var searchAttributesRecursive = function(children) {
    for (var i = 0; i < children.length; ++i) {
      if (children[i].hasOwnProperty('children')) {
        return searchAttributesRecursive(children[i].children);
      }
      else {
        if (children[i].hasOwnProperty('attributes')) {
            if (children[i].attributes.itemprop === "valueWanted") {
              console.log('success')
            }

          }
        }
        return; // probably a problem that breaks the loop
      }
    };

searchAttributesRecursive(startingChildren);

你的回归将打破循环。如果它确实返回,您只想返回:

var searchAttributesRecursive = function(children) {
    for (var i = 0; i < children.length; ++i) {
        if (children[i].hasOwnProperty('children')) {
            var result=searchAttributesRecursive(children[i].children);
            if(result) return result;//if weve found sth, return
        }

        if (children[i].hasOwnProperty('attributes')) {
            if (children[i].attributes.itemprop === "valueWanted1") {
              console.log('success')
              return children[i];//return sth useful
            }

       }
  }
 return false;//nothing found in this and in all childs
};

var elem=searchAttributesRecursive(startingChildren);

以下是一个简短的版本:

请注意,函数需要一个数组,因此如果对象不是数组,则必须使用
findItemprop([dom],“wanted”)

函数findItemprop(数据、值、已找到){
如果(!found)found=[];
data.forEach((节点)=>{
if(node.attributes&&node.attributes.itemprop==value)
发现.推送(节点);
if(node.children)findItemprop(node.children,value,found);
});
发现退货;
}
变量dom=[{
标签:“根”,
儿童:[{
标签:“标题”,
儿童:[{
标签:“div”
}]
}, {
标签:“div”,
id:“主要”,
儿童:[{
标签:“p”,
属性:{
itemprop:“通缉”
}
}]
}, {
标签:“页脚”,
儿童:[{
标签:“span”,
内容:“版权所有2017”,
属性:{
itemprop:“通缉”
}
}]
}]
}];

log(findItemprop(dom,“通缉”)您可以使用
.some()
函数来完成此操作。如果任何迭代返回true,它将返回true,否则它将返回false。因此,对于当前对象中的每个键,您将检查属性是否为
==“attributes”
,如果是,您将检查
itemprop
属性以获得所需的值。如果当前键不是“attributes”,而是“children”
,它将以相同的方式递归并检查每个子对象

var searchAttributesRecursive=函数(obj,valueWanted){
if(对象的obj实例){
if(obj.attributes&&obj.attributes.itemprop==valueWanted){
返回true;
}
if(对象儿童){
返回obj.children.some(函数(_obj){
返回searchAttributesRecursive(_obj,valueWanted);
});
}否则{
返回false;
}
}否则{
返回false;
}
};
var obj={
键入:“x”,
标记名:“y”,
属性:{
“itemprop”:“wantedValue0”
},
儿童:[{
键入:“x”,
标记名:“y”,
属性:{
“itemprop”:“wantedValue1”
},
儿童:[]
},
{
键入:“x”,
标记名:“y”,
属性:{
“itemprop”:“wantedValue2”
},
儿童:[{
键入:“x”,
标记名:“y”,
属性:{
“itemprop”:“wantedValue3”
},
儿童:[]
}]
}
]
};
log(“找到'wantedValue0':”+searchAttributesRecursive(obj,“wantedValue0”);
log(“找到‘wantedValue1’:”+searchAttributesRecursive(obj,“wantedValue1”));
log(“找到‘wantedValue2’:”+searchAttributesRecursive(obj,“wantedValue2”));
log(“找到'wantedValue3':”+searchAttributesRecursive(obj,“wantedValue3”);

log(“找到‘wantedValue4’:”+searchAttributesRecursive(obj,“wantedValue4”))给Jonas w他们的答案加上一点功劳,我只是想帮助纠正围绕递归的一些困惑,希望能让它更容易理解和使用

首先,您将传递一组子对象。这很好,但是在检查它们时,必须从其数组索引中访问它们。我的建议是让函数一次只处理一项。(我将使用Jonas w收集节点的方法,因为可能有多个节点具有此属性。我还将添加属性名称作为参数,使其更具动态性。)

现在您可以一次只关注一个节点。一旦它通过了检查,你就可以继续看孩子们了

function searchAttributesRecursive(currentNode, parameterName, results=[]){
    if(currentNode.attributes && currentNode.attributes[parameterName]){
        results.push(currentNode);
    }
    if(currentNode.children){
        for(var i = 0, len = currentNode.children.length; i < len; ++i){
            searchAttributesRecursive(currentNode.children[i], parameterName, results);
        }
    }
}
…使用包含“itemprop”属性的节点填充
结果
。现在可以使用简单的循环打印属性值:

for(var i = 0, len = results.length; i < len; ++i){
    console.log(i, results[i].attributes.itemprop);
}
for(变量i=0,len=results.length;i
搜索,真的吗?它看起来像一个对象,您正在处理。请添加结构,至少一小部分,它是如何构造的。你真的在寻找字符串“itemprop”@NinaScholz JSON对象已转换为JS对象,不是吗?我添加了对象结构。对象可以有attributes或children属性。@epascarello是的。由于Nina链接,JSON只是一种文本格式。这是一根绳子。除了
JSON
内置JavaScript对象之外,没有所谓的“JSON对象”。但是是的,
JSON.parse
将JSON字符串转换为JavaScript对象。这是一个很小但很重要的区别。重命名
children
参数(而不是属性)可能有助于缓解围绕递归的一些amazingcode12的困惑
children[i]。children
==混乱,
current[i]。children
==不那么混乱。@TheJim01我认为这对OP是一个很好的建议。但是,我希望他的代码看起来相似,这样更容易理解…@Jonasw看起来属性没有定义(TypeError:无法读取未定义的属性'itemprop'))@这是不可能的。它以前在队列中检查过吗?@Jonasw谢谢,它现在正在工作,我知道
function searchAttributesRecursive(currentNode, parameterName, results=[]){
}
function searchAttributesRecursive(currentNode, parameterName, results=[]){
    if(currentNode.attributes && currentNode.attributes[parameterName]){
        results.push(currentNode);
    }
    if(currentNode.children){
        for(var i = 0, len = currentNode.children.length; i < len; ++i){
            searchAttributesRecursive(currentNode.children[i], parameterName, results);
        }
    }
}
var results = [];
searchAttributesRecursive(yourJsObject, "itemprop", results);
for(var i = 0, len = results.length; i < len; ++i){
    console.log(i, results[i].attributes.itemprop);
}