动态遍历深层嵌套对象并累积结果 [英] Dynamically traversing a deep nested object and accumulating results
问题描述
我正在尝试剖析一个深度嵌套的对象.遍历它并将数据拉到一个单层对象,然后与一个更大的对象结合在一起.我可以使用以下代码遍历它,但它不是动态的.就像,这只有在我知道它的 4 个对象很深时才有效.实际上它可以是 1 ->深.我还有一个函数可以检查该级别的值类型并相应地对其进行处理.现在这对我有用
Im trying to dissect a deeply nested object. Traversing it and pulling data to a single level object which then gets married up with a larger object down the line. I am able to traverse it with the following code but its not dynamic. As in, this only works if I know its 4 objects deep. Where in reality it can be 1 -> n deep. I also have a function that checks the type of value at that level and does work on it accordingly. Right now this works for me
run();
function run() {
const topLevelObjects = [{
field: 'pivotvalue0',
value: '111111111',
count: 36,
pivot: [{
field: 'pivotvalue1',
value: 'Y',
count: 27,
pivot: [{
field: 'pivotvalue2',
value: 'Header1',
count: 27,
pivot: [{
field: 'pivotvalue3',
value: 'Value1',
count: 14
},
{
field: 'pivotvalue3',
value: 'Value2',
count: 13
}
]
}]
},
{
field: 'pivotvalue1',
value: 'Z',
count: 9,
pivot: [{
field: 'pivotvalue2',
value: 'Header2',
count: 9,
pivot: [{
field: 'pivotvalue3',
value: 'Value1',
count: 9
}]
}]
}
]
},
{
field: 'pivotvalue0',
value: '222222222',
count: 23,
pivot: [{
field: 'pivotvalue1',
value: 'Y',
count: 23,
pivot: [{
field: 'pivotvalue2',
value: 'Header1',
count: 12,
pivot: [{
field: 'pivotvalue3',
value: 'Value2',
count: 12
}]
},
{
field: 'pivotvalue2',
value: 'Header2',
count: 11,
pivot: [{
field: 'pivotvalue3',
value: 'Value2',
count: 11
}]
}
]
}]
}
]
//pivotResponse.facet_counts.facet_pivot[pivotsString]
const accumulatedPivotInfo = []
//This is assuming you can only pivot 4 deep. Would love to figure out how to make this dynamic.
for (const level0 of topLevelObjects) {
let newPivotInfo = {}
newPivotInfo[level0.field] = level0.value
if (level0.pivot) {
for (const level1 of level0.pivot) {
newPivotInfo = {
...newPivotInfo,
...buildBasedOnType(level1, newPivotInfo)
}
if (level1.pivot) {
for (const level2 of level1.pivot) {
newPivotInfo = {
...newPivotInfo,
...buildBasedOnType(level2, newPivotInfo)
}
if (level2.pivot) {
for (const level3 of level2.pivot) {
newPivotInfo = {
...newPivotInfo,
...buildBasedOnType(level3, newPivotInfo)
}
}
}
}
}
}
}
accumulatedPivotInfo.push(newPivotInfo)
}
console.log(accumulatedPivotInfo)
}
function buildBasedOnType(level, newPivotInfo) {
if (level.field === 'pivotvalue1') {
level.value === 'Y' ? newPivotInfo['pivotvalue1.1'] = level.count : newPivotInfo['pivotvalue1.1'] = 0
level.value === 'N' ? newPivotInfo['pivotvalue1.2'] = level.count : newPivotInfo['pivotvalue1.2'] = 0
level.value === 'Z' ? newPivotInfo['pivotvalue1.3'] = level.count : newPivotInfo['pivotvalue1.3'] = 0
} else if (level.field === 'pivotvalue2' || level.field === 'pivotvalue3') {
newPivotInfo[level.field + 's'] === undefined ? newPivotInfo[level.field + 's'] = new Set([level.value]) : newPivotInfo[level.field + 's'].add(level.value)
} else {
newPivotInfo[level.field] = level.value
}
return newPivotInfo
}
这是我最终输出的样子以及我想要实现的目标
Here is what my final output looks like and what im trying to achieve
pivotInfo = [
{
pivotvalue0: '111111111',
'pivotvalue1.1': 0,
'pivotvalue1.2': 0,
'pivotvalue1.3': 9,
pivotvalue2s: Set { 'Header1', 'Header2' },
pivotvalue3s: Set { 'Value1', 'Value2' }
},
{
pivotvalue0: '222222222',
'pivotvalue1.1': 23,
'pivotvalue1.2': 0,
'pivotvalue1.3': 0,
pivotvalue2s: Set { 'Header1', 'Header2' },
pivotvalue3s: Set { 'Value2' }
}
]
出于某种原因,代码运行器确实可以很好地处理集合.所以这里是 jsfiddle 中设置集合的相同代码:https://jsfiddle.net/x9sa8tqm/
For some reason the code runner does work with sets well. So here is the same code in jsfiddle that sets the sets: https://jsfiddle.net/x9sa8tqm/
希望这足以说明我目前在做什么.现在我有数据可以通过一组值来了解这些对象的深度.所以我可以检查数组长度并知道我需要走多深.使这种动态变化的最佳方法是什么?因此它将弯曲到n"深度而不是编码为 4 的头部.
Hopefully this is enough context to see what Im currently doing. Right now I have data to know how deep these objects will be via an array of values. So I can check the array length and know how deep I need to go. What would be the best way to make this dynamic? So it will flex to 'n' deepness instead of a head coded 4.
谢谢!
推荐答案
使用递归来实现这一点.
Use Recursion to achieve this.
var data = [
{
field: 'pivotvalue0',
value: '200275399',
count: 36,
pivot: [{
field: 'pivotvalue0.1',
value: '200275399',
count: 36,
pivot: [{
field: 'pivotvalue0.2',
value: '200275399',
count: 36,
pivot: []
}]
}]
},
{
field: 'pivotvalue0',
value: '200746617',
count: 23,
pivot: []
}
]
var finalResult = [];
function accumulateValue(data){
data.forEach(item=>{
finalResult.push({
field: item.field,
value: item.value,
count: item.count,
});
if(item.pivot && item.pivot.length){
accumulateValue(item.pivot)
}
})
}
accumulateValue(data)
console.log(finalResult);
这篇关于动态遍历深层嵌套对象并累积结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!