如何在嵌套的 JS 对象中查找特定属性的总和

Posted

技术标签:

【中文标题】如何在嵌套的 JS 对象中查找特定属性的总和【英文标题】:How to find sum of a specific property in nested JS object 【发布时间】:2021-09-28 20:24:49 【问题描述】:

我想计算这个对象中所有“val”的总和。最终输出应该是 113。我尝试搜索但在 *** 上找不到类似的问题。

const object = 
  val: 10,
  child: [
    
      val: 20,
      child: [
        
          val: 25,
          child: []
        ,
        
          val: 28,
          child: []
        
      ]
    ,
    
      val: 30,
      child: []
    
  ]
;

我尝试的是这个。我知道这不是最好的方法,并希望看到更好的方法。

const object = 
  val: 10,
  child: [
    
      val: 20,
      child: [
        
          val: 25,
          child: []
        ,
        
          val: 28,
          child: []
        
      ]
    ,
    
      val: 30,
      child: []
    
  ]
;

function sum() 
 let k = object.val;
 if(object.child.length>0)
 object.child.map(item => 
 
 k += item.val;
 if(item.child.length>0)
 item.child.map(item => k += item.val)
 
 )
 
 
 return k


const result = sum(object);
console.log(result);

你可以在这里找到问题 - https://codesandbox.io/s/young-night-ulnfl?file=/src/index.js

我也在想像 flat() 这样的东西可能会有所帮助,但这仅适用于数组。

【问题讨论】:

这能回答你的问题吗? Find all values by specific key in a deep nested object(而不是推送到数组,而是求和) 另见:Summing nested value if it exists 【参考方案1】:

递归Array#reduce()

const object =  val: 10, child: [ val: 20, child: [ val: 25, child: [] ,  val: 28, child: [] ] ,  val: 30, child: [] ] ;

const sumObjectVals = (arr) => arr
  .reduce((a, obj) => (
    a += (obj.child.length
      ? obj.val + sumObjectVals(obj.child)
      : obj.val), a), 0);

console.log(sumObjectVals([object]))

【讨论】:

【参考方案2】:

你可以创建一个递归节点访问函数。

const tree =  val: 10, child: [ val: 20, child: [ val: 25, child: [] ,  val: 28, child: [] ] ,  val: 30, child: [] ] 

const visitNodes = (obj, visitor, key) => 
  if (typeof obj === 'object') 
    for (let key in obj) 
      visitNodes(obj[key], visitor, key);
    
   else 
    visitor(obj, key);
  
;

let total = 0;
visitNodes(tree, (val, key) => 
  if (key === 'val') 
    total += val;
  
);
console.log(`Total: $total`);

或者,您可以拥有一个可以为您添加所有值的累加器。

编辑:更改了函数签名以采用自定义“子”属性。

const tree =  val: 10, child: [ val: 20, child: [ val: 25, child: [] ,  val: 28, child: [] ] ,  val: 30, child: [] ] 

const accumulateValues = (obj, visitor, childProp = null, acc = 0) => 
  if (typeof obj === 'object') 
    acc += visitor(obj);
    if (Array.isArray(obj[childProp])) 
      acc += obj[childProp].reduce((acc, child) =>
        accumulateValues(child, visitor, childProp, acc), 0);
    
  
  return acc;
;

const total = accumulateValues(tree, ( val ) => val, 'child');
console.log(`Total: $total`);

【讨论】:

【参考方案3】:
const object = 
  val: 10,
  child: [
    
      val: 20,
      child: [
        
          val: 25,
          child: []
        ,
        
          val: 28,
          child: []
        
      ]
    ,
    
      val: 30,
      child: []
    
  ]
;

function sum(obj, summ) 
  summ += obj.val;

  if(obj.child.length > 0) 
    obj.child.forEach(x => summ = sum(x, summ))
  

  return summ;


const result = sum(object, 0);
console.log(result);

【讨论】:

【参考方案4】:

// 可以使用多个reduce数组方法得到结果。

const object = 
  val: 10,
  child: [
    
      val: 20,
      child: [
        
          val: 25,
          child: []
        ,
        
          val: 28,
          child: []
        
      ]
    ,
    
      val: 30,
      child: []
    
  ]
;

const results = object.child.reduce((totals, current)=> 
  const innerResult = current.child.reduce((total, cur) => 
    return total + cur.val
  , 0);
  return totals + current.val + innerResult;
, object.val);

console.log(results);

【讨论】:

以上是关于如何在嵌套的 JS 对象中查找特定属性的总和的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 linq 查询具有嵌套列表的对象?

如何通过猫鼬中的嵌套属性查找

如何获取 CoreData DB 中特定属性的总和?

如何在 Knockout.js 中嵌套对象

你会如何解决这个问题?使用reduce方法计算此数组中嵌套对象值的总和?

从嵌套的对象数组中提取所有特定属性