减少javascript中的嵌套对象

时间:2020-05-30 13:18:42

标签: javascript dictionary object reduce

我有一个结构如下的对象

"Office": {
    "California" : {
        "Contract1": {
            1: {Price: 1000, Count: 5},
            2: {Price: 2000, Count: 11},
            3: {Price: 3000, Count: 3},
            4: {Price: 2000, Count: 1},...
        },
        "Contract2": {
            1: {Price: 7000, Count: 6},
            2: {Price: 1000, Count: 4},
            3: {Price: 67000, Count: 6},
            4: {Price: 500, Count: 2},...
        },
        "Contract3": {
            1: {Price: 4000, Count: 4},
            2: {Price: 4000, Count: 1},
            3: {Price: 5000, Count: 12},
            4: {Price: 5000, Count: 2},...
        }
    },
    "North Carolina" : {
        "Contract1": {
            1: {Price: 7000, Count: 4},
            2: {Price: 7000, Count: 4},
            3: {Price: 7000, Count: 4},
            4: {Price: 7000, Count: 4},...
        },
        "Contract2": {
            1: {Price: 6000, Count: 4},
            2: {Price: 2000, Count: 10},
            3: {Price: 3000, Count: 3},
            4: {Price: 2000, Count: 3},...
        },
        "Contract3": {
            1: {Price: 4000, Count: 5},
            2: {Price: 2000, Count: 4},
            3: {Price: 4000, Count: 3},
            4: {Price: 2000, Count: 4},...
        },...
}

我想将其简化为:

"Office": {
    "California" : {
        "Contract1": {
            1: {Price: 6000, Count: 19},
            2: {Price: 2000, Count: 1},...
        },
        "Contract2": {
            1: {Price: 75000, Count: 16},
            2: {Price: 500, Count: 2},...
        },
        "Contract3": {
            1: {Price: 13000, Count: 17},
            2: {Price: 5000, Count: 2},...
        }
    },
    "North Carolina" : {
        "Contract1": {
            1: {Price: 21000, Count: 12},
            2: {Price: 7, Count: 4},...
        },
        "Contract2": {
            1: {Price: 11000, Count: 17},
            2: {Price: 2000, Count: 3},...
        },
        "Contract3": {
            1: {Price: 10000, Count: 12},
            2: {Price: 2000, Count: 4},...
        },...
}

第一个结构中每个合同下的数字对象代表过去的几个月。在第二个结构中,我想总结前三个数字对象的属性,可以将其称为1。然后第二个3将是2。这些是四分之一。

我认为我可以通过map,reduce和filter的某种组合来做到这一点,但是这些都是数组函数,并且我有一个对象,因此我不确定该怎么做。对于非ES6解决方案,我需要这样做。

任何指导将不胜感激。

2 个答案:

答案 0 :(得分:1)

基于计数,它将动态填充所需的输出

  const data = { "Office": {
"California" : {
    "Contract1": {
        1: {Price: 1000, Count: 5}, 2: {Price: 2000, Count: 11},
        3: {Price: 3000, Count: 3}, 4: {Price: 2000, Count: 1},
        5: {Price: 1000, Count: 5}, 6: {Price: 2000, Count: 11},
        7: {Price: 3000, Count: 3}, 8: {Price: 2000, Count: 1},
        9: {Price: 1000, Count: 5}, 10: {Price: 2000, Count: 11},
        11: {Price: 3000, Count: 3}, 12: {Price: 2000, Count: 1},
    },
    "Contract2": {
        1: {Price: 7000, Count: 6}, 2: {Price: 1000, Count: 4},
        3: {Price: 67000, Count: 6}, 4: {Price: 500, Count: 2},
        5: {Price: 7000, Count: 6}, 6: {Price: 1000, Count: 4},
        7: {Price: 67000, Count: 6}, 8: {Price: 500, Count: 2},
        9: {Price: 7000, Count: 6}, 10: {Price: 1000, Count: 4},
        11: {Price: 67000, Count: 6}, 12: {Price: 500, Count: 2},
    },
    "Contract3": {
        1: {Price: 4000, Count: 4}, 2: {Price: 4000, Count: 1},
        3: {Price: 5000, Count: 12}, 4: {Price: 5000, Count: 2},
        5: {Price: 4000, Count: 4}, 6: {Price: 4000, Count: 1},
        7: {Price: 5000, Count: 12}, 8: {Price: 5000, Count: 2},
        9: {Price: 4000, Count: 4}, 10: {Price: 4000, Count: 1},
        11: {Price: 5000, Count: 12}, 12: {Price: 5000, Count: 2},
    }
},
"North Carolina" : {
    "Contract1": {
        1: {Price: 7000, Count: 4}, 2: {Price: 7000, Count: 4},
        3: {Price: 7000, Count: 4}, 4: {Price: 7000, Count: 4},
        5: {Price: 7000, Count: 4}, 6: {Price: 7000, Count: 4},
        7: {Price: 7000, Count: 4}, 8: {Price: 7000, Count: 4},
        9: {Price: 7000, Count: 4}, 10: {Price: 7000, Count: 4},
        11: {Price: 7000, Count: 4}, 12: {Price: 7000, Count: 4},
    },
    "Contract2": {
        1: {Price: 6000, Count: 4}, 2: {Price: 2000, Count: 10},
        3: {Price: 3000, Count: 3}, 4: {Price: 2000, Count: 3},
        5: {Price: 6000, Count: 4}, 6: {Price: 2000, Count: 10},
        7: {Price: 3000, Count: 3}, 8: {Price: 2000, Count: 3},
        9: {Price: 6000, Count: 4}, 10: {Price: 2000, Count: 10},
        11: {Price: 3000, Count: 3}, 12: {Price: 2000, Count: 3},
    },
    "Contract3": {
        1: {Price: 4000, Count: 5}, 2: {Price: 2000, Count: 4},
        3: {Price: 4000, Count: 3}, 4: {Price: 2000, Count: 4},
        5: {Price: 4000, Count: 5}, 6: {Price: 2000, Count: 4},
        7: {Price: 4000, Count: 3}, 8: {Price: 2000, Count: 4},
        9: {Price: 4000, Count: 5}, 10: {Price: 2000, Count: 4},
        11: {Price: 4000, Count: 3}, 12: {Price: 2000, Count: 4},
    },
},
} }

let count = 3;
for(var parent in data['Office']){
  let child1 = data['Office'][parent];
  for(var con in child1){
    child1[con] = Object.keys(child1[con]).reduce((acc,ele,index)=>{
        let key = Math.trunc(index / count);
       return {...acc,...{[key+1]: (key+1 in acc) ? {Price:acc[key+1]['Price']+child1[con][ele]['Price'],Count:acc[key+1]['Count']+child1[con][ele]['Count']} : child1[con][ele]}}
    },{})
  }
}
console.log(data)

答案 1 :(得分:0)

您可以使用我编写的适用于对象的特殊map函数以这种方式进行操作

const { pipe, fork, map, reduce, get } = rubico

const data = { "Office": {
    "California" : {
        "Contract1": {
            1: {Price: 1000, Count: 5}, 2: {Price: 2000, Count: 11},
            3: {Price: 3000, Count: 3}, 4: {Price: 2000, Count: 1},
            5: {Price: 1000, Count: 5}, 6: {Price: 2000, Count: 11},
            7: {Price: 3000, Count: 3}, 8: {Price: 2000, Count: 1},
            9: {Price: 1000, Count: 5}, 10: {Price: 2000, Count: 11},
            11: {Price: 3000, Count: 3}, 12: {Price: 2000, Count: 1},
        },
        "Contract2": {
            1: {Price: 7000, Count: 6}, 2: {Price: 1000, Count: 4},
            3: {Price: 67000, Count: 6}, 4: {Price: 500, Count: 2},
            5: {Price: 7000, Count: 6}, 6: {Price: 1000, Count: 4},
            7: {Price: 67000, Count: 6}, 8: {Price: 500, Count: 2},
            9: {Price: 7000, Count: 6}, 10: {Price: 1000, Count: 4},
            11: {Price: 67000, Count: 6}, 12: {Price: 500, Count: 2},
        },
        "Contract3": {
            1: {Price: 4000, Count: 4}, 2: {Price: 4000, Count: 1},
            3: {Price: 5000, Count: 12}, 4: {Price: 5000, Count: 2},
            5: {Price: 4000, Count: 4}, 6: {Price: 4000, Count: 1},
            7: {Price: 5000, Count: 12}, 8: {Price: 5000, Count: 2},
            9: {Price: 4000, Count: 4}, 10: {Price: 4000, Count: 1},
            11: {Price: 5000, Count: 12}, 12: {Price: 5000, Count: 2},
        }
    },
    "North Carolina" : {
        "Contract1": {
            1: {Price: 7000, Count: 4}, 2: {Price: 7000, Count: 4},
            3: {Price: 7000, Count: 4}, 4: {Price: 7000, Count: 4},
            5: {Price: 7000, Count: 4}, 6: {Price: 7000, Count: 4},
            7: {Price: 7000, Count: 4}, 8: {Price: 7000, Count: 4},
            9: {Price: 7000, Count: 4}, 10: {Price: 7000, Count: 4},
            11: {Price: 7000, Count: 4}, 12: {Price: 7000, Count: 4},
        },
        "Contract2": {
            1: {Price: 6000, Count: 4}, 2: {Price: 2000, Count: 10},
            3: {Price: 3000, Count: 3}, 4: {Price: 2000, Count: 3},
            5: {Price: 6000, Count: 4}, 6: {Price: 2000, Count: 10},
            7: {Price: 3000, Count: 3}, 8: {Price: 2000, Count: 3},
            9: {Price: 6000, Count: 4}, 10: {Price: 2000, Count: 10},
            11: {Price: 3000, Count: 3}, 12: {Price: 2000, Count: 3},
        },
        "Contract3": {
            1: {Price: 4000, Count: 5}, 2: {Price: 2000, Count: 4},
            3: {Price: 4000, Count: 3}, 4: {Price: 2000, Count: 4},
            5: {Price: 4000, Count: 5}, 6: {Price: 2000, Count: 4},
            7: {Price: 4000, Count: 3}, 8: {Price: 2000, Count: 4},
            9: {Price: 4000, Count: 5}, 10: {Price: 2000, Count: 4},
            11: {Price: 4000, Count: 3}, 12: {Price: 2000, Count: 4},
        },
    },
} }

const addContracts = (total, contract) => ({
  Price: total.Price + contract.Price,
  Count: total.Count + contract.Count,
})

const monthNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

const sumMonthsToQuarters = contract => {
  const quartered = {
    1: { Price: 0, Count: 0 },
    2: { Price: 0, Count: 0 },
    3: { Price: 0, Count: 0 },
    4: { Price: 0, Count: 0 },
  }
  for (const monthNum of monthNumbers) {
    const quarterNum = Math.ceil(monthNum / 3)
    quartered[quarterNum] = addContracts(quartered[quarterNum], contract[monthNum])
  }
  return quartered
}

const x = map(map(map(sumMonthsToQuarters)))(data)

console.log(JSON.stringify(x))
<script src="https://unpkg.com/rubico/index.js" crossorigin></script>

相关问题