js深度优先和广度优先遍历语法树
在遍历html语法树中用到了深度优先遍历和广度优先遍历,就自己用js实现了下
//treeSearch.js
//广度遍历html节点
function breadthSearch(item, childProp='children'){
const nodeList=[item]
let index=0;
while (index<nodeList.length){
const node=nodeList[index++];
if(node[childProp]){
for(let k in node[childProp]){
nodeList.push(node[childProp][k]);
}
}
}
return nodeList;
}
//深度遍历html节点
function depthSearch(node,childProp='children'){
const nodeList=[]
const depthEach=function(item){
nodeList.push(item);
if(item[childProp]){
for(let k in item[childProp]){
depthEach(item[childProp][k]);
}
}
}
depthEach(node);
return nodeList;
}
//广度遍历
function breadthEach(node,filter) {
const nodeList=[]
const itemList=[node]
let index=0;
while (index<itemList.length){
const item=itemList[index++];
if(filter(item)){
nodeList.push(item);
}
for(let k in item){
if(item[k]&&typeof item[k]==='object'){
itemList.push(item[k])
}
}
}
return nodeList;
}
//深度遍历
function depthEach(node,filter){
const nodeList=[]
const depthEach=function(item){
if(filter(item)){
nodeList.push(item);
}
for(let k in item){
if(item[k]&&typeof item[k]==='object'){
depthEach(item[k]);
}
}
}
depthEach(node);
return nodeList;
}
module.exports={
breadthSearch,depthSearch,breadthEach,depthEach
}
测试
const fs=require('fs')
const {depthEach}=require('./utils/treeSearch')
const code=fs.readFileSync('./test.js').toString()
const ast=require("babylon").parse(code, {
// parse in strict mode and allow module declarations
sourceType: "module",
plugins: [
// enable jsx and flow syntax
"jsx",
"flow"
]
});
const arr=depthEach(ast,function (node) {
return node.type==='VariableDeclaration'
})
console.log(arr.length)