繁体   English   中英

动态迭代嵌套对象并使用递归将特定值推送到单独的数组中

[英]Iterate nested objects dynamically and push the specific values into separate array using recursion

我正在尝试基于键返回值数组的 java 脚本递归函数。

嵌套的 JavaScript 对象的深度未知。 该函数正在工作,但值没有正确返回..当我从另一个函数调用这个递归函数时,我只得到第一个迭代值。 但是我可以控制台并查看相同函数中的值。

这是我的 json

{
    "id": 0,
    "name": "Root Entity",
    "children": [{
        "id": 1,
        "name": "REAT",
        "children": [{
            "id": 2,
            "name": "Business",
            "children": [{
                "id": 3,
                "name": "Region 1",
                "children": [{
                    "id": 5,
                    "name": "Area 1",
                    "children": [
                    {
                        "dealerId": 14,
                        "name": "lead 1"
                    }, 
                    {
                        "dealerId": 15,
                        "name": "lead 2"
                    }, 
                    {
                        "dealerId": 16,
                        "name": "lead 3"
                    }, 
                    {
                        "dealerId": 17,
                        "name": "lead 4"
                    }, 
                    {
                        "dealerId": 18,
                        "name": "lead 5"
                    }, 
                    {
                        "dealerId": 19,
                        "name": "lead 6"
                    }, {
                        "dealerId": 20,
                        "name": "lead 7"
                    }],
                    "kpi_1_met": 0,
                    "lead_num": 0,
                }, {
                    "id": 6,
                    "name": "Area 2",
                    "children": [{
                        "dealerId": 31
                        "name": "lead 1"
                    }] 
                }]
            }]
        }]
    }]

}

这是我尝试过的递归函数

async function outputArray(output, leadInfo, req, res) {
    let resoutput = output.children,
        constructedArray = [],
        obj = {};
        // dealerName, entityList = await entityNames(req, res);
    let leagueData = [];

    resoutput.forEach((dataArray) => {
        if (dataArray.hasOwnProperty('children') &&
            dataArray.children instanceof Array &&
            dataArray.children.length > 0) {
            // console.log("================ dataArray.children", dataArray.children[0]['name']);
            for (let i in dataArray.children) {
                obj = { 'regionId': dataArray.children[i].id, 'region': dataArray.children[i].name};
                outputArray(dataArray.children[i], leadInfo, req, res);
                leagueData.push(obj);
                // console.log("================ leagueData ===============", leagueData);
            }

        } else {
            if (dataArray.hasOwnProperty('name'))
                // console.log("================ else", dataArray.name);
        }
    });
    // console.log("================ leagueData outside =============", leagueData);
    return leagueData;
}

我在下面的另一个函数中调用上面的递归函数

async function dataTable(output, leadInfo, req, res) {
    let obj = {},
        data = await outputArray(output, leadInfo, req, res, obj);

    // here First Iterated data only coming
    // console.log("data from data Table", data)
}    

输出应该是

[ 
  { regionId: 3, areaId: 5, dealerId: 14, name: 'lead 1', region: 'Region 1', area: 'Area 1' }, 
  { regionId: 3, areaId: 5, dealerId: 31, name: 'lead 1', region: 'Region 1', area: 'Area 2' } 
]

它应该根据树的层次结构填充

请任何人帮我解决这个问题。 我正在努力把它弄出来。

这可能是您正在寻找的


  
 
  
  
let a = {
    "id": 0,
    "name": "Root Entity",
    "children": [{
        "id": 1,
        "name": "REAT",
        "children": [{
            "id": 2,
            "name": "Business",
            "children": [{
                "id": 3,
                "name": "Region 1",
                "children": [{
                    "id": 5,
                    "name": "Area 1",
                    "children": [
                    {
                        "id": 14,
                        "name": "lead 1"
                    }, 
                    {
                        "id": 15,
                        "name": "lead 2"
                    }, 
                    {
                        "id": 16,
                        "name": "lead 3"
                    }, 
                    {
                        "id": 17,
                        "name": "lead 4"
                    }, 
                    {
                        "id": 18,
                        "name": "lead 5"
                    }, 
                    {
                        "id": 19,
                        "name": "lead 6"
                    }, {
                        "id": 20,
                        "name": "lead 7"
                    }],
                    "kpi_1_met": 0,
                    "lead_num": 0,
                }, {
                    "id": 6,
                    "name": "Area 2",
                    "children": [{
                        "id": 31,
                        "name": "lead 1"
                    }] 
                }]
            }]
        }]
    }]

}


function test(data) {
            let response = [];
            if (Array.isArray(data)) {
                for (let o of data) {
                    response.push({ id: o.id, name: o.name });
                    if (o.hasOwnProperty('children') && o.children.length > 0) {
                        let child = test(o.children);
                        response = response.concat(child);
                    }
                }
            } else {
                response.push({ id: data.id, name: data.name });
                if (data.hasOwnProperty('children') && data.children.length > 0) {
                    let child = test(data.children);
                    response = response.concat(child);
                }
            }
            return response;
        }
   
        let res = test(a);
        console.log(res)

您应该保存递归调用的结果

outputArray(dataArray.children[i], leadInfo, req, res);

我不确定我是否正确回答了这个问题。 如果您只想迭代数据并将其推送到数组,以下代码将有所帮助。

<script>
var data = {
    "id": 0,
    "name": "Root Entity",
    "children": [{
        "id": 1,
        "name": "REAT",
        "children": [{
            "id": 2,
            "name": "Business",
            "children": [{
                "id": 3,
                "name": "Region 1",
                "children": [{
                    "id": 5,
                    "name": "Area 1",
                    "children": [
                    {
                        "id": 14,
                        "name": "lead 1"
                    }, 
                    {
                        "id": 15,
                        "name": "lead 2"
                    }, 
                    {
                        "id": 16,
                        "name": "lead 3"
                    }, 
                    {
                        "id": 17,
                        "name": "lead 4"
                    }, 
                    {
                        "id": 18,
                        "name": "lead 5"
                    }, 
                    {
                        "id": 19,
                        "name": "lead 6"
                    }, {
                        "id": 20,
                        "name": "lead 7"
                    }],
                    "kpi_1_met": 0,
                    "lead_num": 0
                }, {
                    "id": 6,
                    "name": "Area 2",
                    "children": [{
                        "id": 31,
                        "name": "lead 1"
                    }] 
                }]
            }]
        }]
    }]

}
let leagueData = [];
function outputArray(output, leadInfo, req, res) {
    let resoutput = output.children,
        obj = { 'regionId': output.id, 'region': output.name};                
        leagueData.push(obj);
        if (output.hasOwnProperty('children') &&
            output.children instanceof Array &&
            output.children.length > 0) {            
            for (let i in output.children) {                
                console.log("*************** leagueData ===============", output.children[i]);
                outputArray(output.children[i], leadInfo, req, res);
            }

        }

}
 function dataTable(output, leadInfo, req, res) {
    let obj = {},
        data =  outputArray(output, leadInfo, req, res, obj);
    // here First Iterated data only coming
     console.log("data from data Table", leagueData)
} 
dataTable(data,"","","");
</script>

我并不完全清楚这是否是您要查找的内容,但这里有一种技术可以使层次结构变平,将祖先名称/ID 压缩到叶节点的属性中:

 const nameToKey = (name) => name .replace(/\\s*\\d+$/, '') .toLowerCase () const flattenHierarchy = (node, desc = {}, {name, id, children} = node) => children && children .length > 0 ? children .flatMap (child => flattenHierarchy (child, { ...desc, [nameToKey (name)]: name, [nameToKey (name) + 'Id']: id })) : [{...desc, ...node}] const data = {"children": [{"children": [{"children": [{"children": [{"children": [{"dealerId": 14, "name": "lead 1"}, {"dealerId": 15, "name": "lead 2"}, {"dealerId": 16, "name": "lead 3"}, {"dealerId": 17, "name": "lead 4"}, {"dealerId": 18, "name": "lead 5"}, {"dealerId": 19, "name": "lead 6"}, {"dealerId": 20, "name": "lead 7"}], "id": 5, "kpi_1_met": 0, "lead_num": 0, "name": "Area 1"}, {"children": [{"dealerId": 31, "name": "lead 1"}], "id": 6, "name": "Area 2"}], "id": 3, "name": "Region 1"}], "id": 2, "name": "Business"}], "id": 1, "name": "REAT"}], "id": 0, "name": "Root Entity"} console .log (flattenHierarchy (data))

这将生成一个如下所示的对象数组:

  {
    "root entity": "Root Entity",
    "root entityId": 0,
    "reat": "REAT",
    "reatId": 1,
    "business": "Business",
    "businessId": 2,
    "region": "Region 1",
    "regionId": 3,
    "area": "Area 1",
    "areaId": 5,
    "dealerId": 14,
    "name": "lead 1"
  }

在基本情况下,当我们位于children -> children -> children层次结构中的叶节点时,我们返回我们构建的对象,其中附加了所有叶节点的属性。 如果我们不在叶子上,那么我们将当前的 name/id 属性附加到我们的工作对象,并使用这个增强的工作对象递归调用每个子对象上的函数,然后将它们的结果flatMap到单个数组中。

这与您建议的输出不完全匹配。 首先,有更多结果,输入中的每个叶节点都有一个结果。 我猜这很好,您只是提供样本而不是完整的预期结果。 如果不是,您根据什么标准选择要返回的节点? 其次,这里包含的层次结构还有几个额外的属性,比如reatIdroot entity 如果你不想在输出中出现这些,你如何决定排除它们?

最后,虽然我尝试将名称转换为有用的键,但这是猜测,而且感觉不对。 将字符串数据值转换为对象键让我很担心; 但也许这正是你想要的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM