[英]How to iterate through an array of objects and push all the separate object values to separate arrays
[英]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
到单个数组中。
这与您建议的输出不完全匹配。 首先,有更多结果,输入中的每个叶节点都有一个结果。 我猜这很好,您只是提供样本而不是完整的预期结果。 如果不是,您根据什么标准选择要返回的节点? 其次,这里包含的层次结构还有几个额外的属性,比如reatId
和root entity
。 如果你不想在输出中出现这些,你如何决定排除它们?
最后,虽然我尝试将名称转换为有用的键,但这是猜测,而且感觉不对。 将字符串数据值转换为对象键让我很担心; 但也许这正是你想要的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.