首页 > 解决方案 > 在每个级别生成聚合直到父级

问题描述

给定如下 JSON

{
  "main": {
    "sub1": {
      "cat": {
        "subcat1":{
          "count": 1
        },
        "subcat2":{
          "count": 2
        }
      }
    },
    "sub2": {
      "cat": {
        "subcat1":{
          "count": 3
        },
        "subcat2":{
          "count": 5
        }
      }
    }
  }
}

需要将子级的计数汇总到其直接父级直到顶级父级,如下所示

{
  "main": {
    "count": 11,
    "sub1": {
      "count": 3,
      "cat": {
        "count": 3,
        "subcat1":{
          "count": 1
        },
        "subcat2":{
          "count": 2
        }
      }
    },
    "sub2": {
      "count": 8,
      "cat": {
        "count": 8,
        "subcat1":{
          "count": 3
        },
        "subcat2":{
          "count": 5
        }
      }
    }
  }
}

试图为相同的逻辑思考,无法写任何东西。什么是正确的代码/逻辑?一个是肯定的,我需要某种递归来不断增加计数直到父级。

标签: javascriptrecursion

解决方案


这与 Mulan 的答案没有太大区别,但它显示了相同的过程,但语法略有不同:

const sum = (ns) => ns .reduce ((a, b) => a + b, 0)

const total = (
  {count, ...rest},
  kids = Object .entries (rest) .map (([k, v]) => [k, total (v)]),
  kidsCount = sum (kids .map (([k, v]) => v .count))
) => count == undefined 
  ? Object .fromEntries ([['count', kidsCount], ...kids])
  : {count, ...rest}

const data = {main: {sub1: {cat: {subcat1: {count: 1}, subcat2: {count: 2}}}, sub2: {cat: {subcat1: {count: 3}, subcat2: {count: 5}}}}}

console .log (total (data))
.as-console-wrapper {max-height: 100% !important; top: 0}

如果一个属性存在,我们就提取count它,然后在该对象的其他属性上递归,使它们以有用的形式为Object .fromEntries. 从这些中,我们提取和求和count属性,然后,如果count已经存在,我们返回原始对象的副本,如果不存在,我们向kids属性添加一个条目,并调用Object .fromEntries它。

请注意,我们count在此处向根目录添加了一个属性,该属性不在您请求的输出中,但对我来说很有意义。如果你不想这样,你可以添加一个包装函数,也许像(data) => ({main: total (data .main || {})}).

这使用了一些可选的默认参数。有时这是一个坏主意。如果您想避免它们,我们可以将它们包含在 IIFE 中,如下所示:

const total = ({count, ...rest}) => ((
  kids = Object .entries (rest) .map (([k, v]) => [k, total (v)]),
  kidsCount = sum (kids .map (([k, v]) => v .count))
) => count == undefined 
  ? Object .fromEntries ([['count', kidsCount], ...kids])
  : {count, ...rest}
) () 

或者我们可以遵循 Mulan 的技术,其中局部变量意味着您不需要它们。


推荐阅读