一组节点的递归回调

时间:2016-11-10 14:59:20

标签: javascript recursion callback

我有一个树结构(jstree.js),它是一个DOM元素列表。对于每个元素,我检查它是否是父元素,选择它的子元素,并检查父元素状态,...

我需要将树元素解析为一个对象数组。如果元素是父元素,则会为其子对象的数组提供一个附加属性。递归检查这些子对象。

这是我尝试将DOM元素列表解析成的基本结构。 这是我要找的输出

 [ {s:0,c:[ {s:1}, {s:2,c:[s:3]}, {s:4} ]} ]

这是基本的递归函数: 我检查节点的type()。如果它是父母,我试图使用回调来递归子集。如果它是子元素,那么我返回id属性

 function Parse3(rootelem,OBJ,freduce) {
                function type(e){
                    //var e = new Element(root.id)
                    // return !e.isParent ? {'sibling':e.jstxt} : freduce( parent, cb)
                    if (!e.isParent){
                        console.log('- - - CHILD - - -', e.jstxt )
                        return {'sibling':e.jstxt}
                        }
                    if (e.isParent) {
                        console.log('- - - PARENT - - -', e.jstxt )
                        return freduce(OBJ, e, function(i){
                            for ( var i=0; i<e.numchildren; i++ ){
                                console.log('recurse',i ,' ', type( e.childElements[i]) );
                                type( e.childElement[i] )
                            }})
                    }
                }//close type
                return type(rootelem)
            }//Parse3

接下来,(我让它使用原始类型)但是因为我正在处理方法,所以我返回一个包含cb的reduce函数。

   function freduce(OBJ, e,cb){
        OBJ.push( {'sibling':e.jstxt, 'xml':[] }  )
        var obl= OBJ.length-1 == undefined ? 0 : OBJ.length-1
        OBJ[ obl ].xml.push( cb )
        return OBJ
       }

如何迭代选定的子节点。我对javascript有点新,我不太确定我用来迭代孩子的回调逻辑。此外,我不确定如何将子属性减少为元素对象。

(在处理嵌套结构时,我能够使用它来处理基元(数字)。处理对象并迭代子元素集会导致问题...)

任何建议都表示赞赏!

1 个答案:

答案 0 :(得分:1)

你真的不需要致电freduce,这只会使事情复杂化。您可以在类型函数内创建xml属性,而不需要整个调用和回调模式。

此外,您应该尝试不要传递OBJ:而是从递归返回值构建它,直到最终返回值:这是调用者获取结果的方式:

function parse3(rootelem) {
    function type(e){
        var obj = {'sibling': e.jstxt};
        if (e.isParent){
            obj.xml = [];
            for (var i=0; i<e.numchildren; i++ ){
                obj.xml.push(type(e.childElement[i]));
            }
        }
        return obj;
    }
    return type(rootelem);
}

注意:最好不要用所有大写字母命名变量,这通常用于表示常量原始值。第一个字母也不应该大写,因为它主要用于构造函数/类名。

进一步改进:

使用上面的代码,函数parse3本质上与函数type完全不同:它们都采用相同的参数并返回相同类型的信息。

此外,您可以使用childElement函数迭代map列表,或使用Array.from回调迭代(如果它不是真正的数组)。然后,使用Object.assign

在一个表达式中执行所有操作也变得很好
function parse3(e) {
    return Object.assign ({sibling: e.jstxt},
        e.isParent ? { xml: Array.from(e.childElement, parse3) } : {});
}