【问题标题】:Looping through Javascript object to add subtotals based on child objects循环遍历 Javascript 对象以添加基于子对象的小计
【发布时间】:2015-09-10 00:00:05
【问题描述】:

我有一个 JavaScript 对象如下:

{
   "name":"root",
   "children":[
      {
         "name":"Oct 2014",
         "children":[
            {
               "name":"Books",
               "value":106223,
               "formattedValue":"$106,223"
            },
            {
               "name":"Electronics",
               "value":983933,
               "formattedValue":"$983,933"
            }
         ]
      },
      {
         "name":"Nov 2014",
         "children":[
            {
               "name":"Books",
               "value":117588.7,
               "formattedValue":"$117,589"
            },
            {
               "name":"Electronics",
               "value":992779,
               "formattedValue":"$992,779"
            }
         ]
      }
   ]
}

我想知道如何循环遍历对象的最低子对象,并以务实的方式向后工作,为每个父对象添加一个“值”元素,其中值是子对象的总数。所以在上面的例子中,这就是我想要得到的结果:

{
   "name":"root",
   "children":[
      {
         "name":"Oct 2014",
         "children":[
            {
               "name":"Books",
               "value":106223,
               "formattedValue":"$106,223"
            },
            {
               "name":"Electronics",
               "value":983933,
               "formattedValue":"$983,933"
            }
         ],
         "value":10900156
      },
      {
         "name":"Nov 2014",
         "children":[
            {
               "name":"Books",
               "value":117588.7,
               "formattedValue":"$117,589"
            },
            {
               "name":"Electronics",
               "value":992779,
               "formattedValue":"$992,779"
            }
         ],
         "value":1110367.7
      }
   ]
}

有人可以指导我如何找到最底层的孩子,并将每个孩子的价值加到父母身上,形成小计吗?

到目前为止我已经弄清楚的事情:

  • 对象中的子项数量:root.children.length。
  • 循环遍历顶级子节点:
for(var i = 0; i < root.children.length;i++){
var obj = root.children[i];
console.log("name: "+obj["name"]);
console.log("value: "+obj["value"]);
}

注意:不能保证数据集始终具有相同的“深度”。虽然在这种情况下,对象有 2 个级别,但在其他情况下,它可能或多或少。我正在尝试在循环中解释这一点。

当我想出更多事情时会更新...感谢任何人在此期间提供的任何输入!

【问题讨论】:

  • 递归就是你要找的
  • @hindmost,递归在这里可能无济于事,因为父子之间的结构不一致。
  • @loco,最底层的孩子总是比根节点低 2 层吗?如果不是,请解释。
  • @Jonathan M,不,不幸的是没有。我正在将可视化集成到分析平台中。每个父母有多少孩子取决于使用的数据集,这些数据集往往很容易调整,所以这也需要是动态的。但是最底层的孩子总是应该有一个 value 和一个 name 元素。
  • 我在想也许完整的 JSON 对象可以存储在 var 中。可以调用一个函数来遍历最底层的父级,并将子级的 value 元素的总和作为 value 元素添加到父级,如果它还没有的话。然后向后工作,直到最上面的父节点有一个值节点及其子节点的总和。还在琢磨如何在代码中设计这个功能。

标签: javascript loops


【解决方案1】:

如果没有正确理解请求,首先抱歉。

这是我迄今为止尝试过的:

var json = {
  "name":"root",
  "children":[
    {
      "name":"Oct 2014",
      "children":[
        {
          "name":"Books",
          "value":106223,
          "formattedValue":"$106,223"
        },
        {
          "name":"Electronics",
          "value":983933,
          "formattedValue":"$983,933"
        }
      ]
    },
    {
      "name":"Nov 2014",
      "children":[
        {
          "name":"Books",
          "value":117588.7,
          "formattedValue":"$117,589"
        },
        {
          "name":"Electronics",
          "value":992779,
          "formattedValue":"$992,779"
        }
      ]
    }
  ]
};

(function processCurrent(object) {
  var processResult;

  object.value = object.value || 0;

  if (object.children) {
    for (var i=0;i<object.children.length;i++) {
      if (processResult = processCurrent(object.children[i])) {
        object.value += processResult;
      }
    }
  }

  return object.value;
})(json);

console.log(JSON.stringify(json));

这会递归地遍历您的对象并计算每个节点的所有子节点的总和。

【讨论】:

  • 感谢您的回答,两种方法都有效,但我更喜欢@J4G 的回答清晰。
【解决方案2】:

递归确实是您正在寻找的。​​p>

function getChildrenValue (parent) {
   if (parent.children) {
      var value = 0;
      for (var i=0;i<parent.children.length;i++) {
         var child = parent.children[i];
         value += getChildrenValue(child);
      }
      parent.value = value;
   }
   return parent.value;
}

//var root = yourJSONData    
getChildrenValue(root);
console.log(root);

【讨论】:

  • 有一个正确的算法实现,我们都单独得出。不过,我认为我的实现要清晰一些。
【解决方案3】:

这将为您做到这一点:

var jsonData = {
"name":"root",
"children":[
   {
      "name":"Oct 2014",
      "children":[
         {
            "name":"Books",
            "value":106223,
            "formattedValue":"$106,223"
         },
         {
            "name":"Electronics",
            "value":983933,
            "formattedValue":"$983,933"
         }
      ]
   },
   {
      "name":"Nov 2014",
      "children":[
         {
            "name":"Books",
            "value":117588.7,
            "formattedValue":"$117,589"
         },
         {
            "name":"Electronics",
            "value":992779,
            "formattedValue":"$992,779"
         }
      ]
   }
]
}

jsonData.children.map(function (obj) {
    return obj.value = obj.children.reduce(function(prev, cur){
       return prev.value + cur.value;
    })
})
console.log(jsonData);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-11
    • 1970-01-01
    • 2021-06-01
    • 2014-07-14
    • 2013-03-09
    • 2015-09-16
    相关资源
    最近更新 更多