递归函数不返回对象值的总和

时间:2015-12-30 07:46:23

标签: javascript

为什么sumundefined。我究竟做错了什么?

var testData1 = [{
  "name": "Doctors",
  "category": "Doctors",
  "subCategory": [{
    "name": "Likes",
    "category": "Likes",
    "subCategory": [{
      "name": "Visit",
      "category": "Visit",
      "subCategory": [{
        "name": "Charges",
        "category": "Charges",
        "subCategory": null,
        "val": 30
      }]
    }]
  }, {
    "name": "Dislikes",
    "category": "Dislikes",
    "subCategory": [{
      "name": "Quality",
      "category": "Quality",
      "subCategory": [{
        "name": "Appointment",
        "category": "Appointment",
        "subCategory": null,
        "val": 50
      }, {
        "name": "Care",
        "category": "Care",
        "subCategory": null,
        "val": 70
      }, {
        "name": "Attentive ",
        "category": "Attentive ",
        "subCategory": null,
        "val": 90
      }]
    }]
  }, {
    "name": "Neutral",
    "category": "Neutral",
    "subCategory": [{
      "name": "Professional ",
      "category": "Professional ",
      "subCategory": [{
        "name": "Ease",
        "category": "Ease",
        "subCategory": null,
        "val": 50
      }, {
        "name": "Competent ",
        "category": "Competent ",
        "subCategory": null,
        "val": 40
      }, {
        "name": "Availability",
        "category": "Availability",
        "subCategory": null,
        "val": 80
      }]
    }]
  }],
  "index": 6
}, {
  "name": "Service",
  "category": "Service",
  "subCategory": [{
    "name": "Likes",
    "category": "Likes",
    "subCategory": [{
      "name": "Environment",
      "category": "Environment",
      "subCategory": [{
        "name": "Professionalism ",
        "category": "Professionalism ",
        "subCategory": null,
        "val": 50
      }, {
        "name": "Room",
        "category": "Room",
        "subCategory": null,
        "val": 30
      }, {
        "name": "Parking",
        "category": "Parking",
        "subCategory": null,
        "val": 20
      }]
    }, {
      "name": "Availability",
      "category": "Availability",
      "subCategory": [{
        "name": "Competent ",
        "category": "Competent ",
        "subCategory": null,
        "val": 30
      }]
    }]
  }, {
    "name": "Dislikes",
    "category": "Dislikes",
    "subCategory": [{
      "name": "Management",
      "category": "Management",
      "subCategory": [{
        "name": "Staff",
        "category": "Staff",
        "subCategory": null,
        "val": 50
      }, {
        "name": "Operations",
        "category": "Operations",
        "subCategory": null,
        "val": 70
      }]
    }, {
      "name": "Nurses",
      "category": "Nurses",
      "subCategory": [{
        "name": "Medicine",
        "category": "Medicine",
        "subCategory": null,
        "val": 30
      }]
    }]
  }, {
    "name": "Neutral",
    "category": "Neutral",
    "subCategory": [{
      "name": "Serving",
      "category": "Serving",
      "subCategory": [{
        "name": "Took long time",
        "category": "Took long time",
        "subCategory": null,
        "val": 50
      }, {
        "name": "Rude",
        "category": "Rude",
        "subCategory": null,
        "val": 40
      }, {
        "name": "Seated",
        "category": "Seated",
        "subCategory": null,
        "val": 80
      }]
    }]
  }],
  "index": 16
}];

function addSum(data) {
  data.forEach(function(d, index) {
    if (Array.isArray(d.subCategory)) {
      return (0 + addSum(d.subCategory));

    } else {

      document.write('<pre>' + JSON.stringify(d.val, 0, 4) + '</pre>');
      return d.val;
    }
  });
}
var sum = addSum(testData1);
alert(sum);

4 个答案:

答案 0 :(得分:4)

您的退货不属于addSum,属于forEach,这就是为什么addSum不返回任何内容(未定义)。
Array.prototype.forEach并不期望返回值,也不能用于计算总和或其他内容。

您可以利用Array.prototype.reduce来获得结果:

function sum(arr)
{
  return arr.reduce(function(a, b) { 
    return Array.isArray(b.subCategory) ? a + sum(b.subCategory) : a + b.val;
  }, 0);
}

sum(testData1);

或使用ECMAScript 6箭头功能:

var sum = arr => arr.reduce((a, b) => Array.isArray(b.subCategory) 
    ? a + sum(b.subCategory) 
    : a + b.val, 0);

工作JSFiddle demo

答案 1 :(得分:2)

.forEach您无法返回值,这就是您获得undefined的原因,对于这种情况,更合适的.reduce方法

function addSum(data) {
  return data.reduce(function (p, c) {
    return p + (Array.isArray(c.subCategory) ? addSum(c.subCategory) : c.val);
  }, 0);
}

Example

或者如果你想使用.forEach,你可以这样做

function addSum(data) {
  return function sum(data, result) {
    data.forEach(function (element) {
      result = Array.isArray(element.subCategory) 
        ? sum(element.subCategory, result)
        : result + element.val;
    });

    return result;
  }(data, 0);
}

Example

答案 2 :(得分:0)

你不能从你的foreach返回,只能从你的函数中返回。这是您的功能的工作版本:

function addSum(data,tot) {
  tot = tot || 0;
  data.forEach(function(d, index) {
    if (Array.isArray(d.subCategory)) {
      tot = addSum(d.subCategory, tot);
    } else {
      tot += parseInt(d.val);
      document.write('<pre>' + d.val + ' - ' + tot + ' </pre>');
    }
  });
  return tot;
}

和jsfiddle:

https://jsfiddle.net/mckinleymedia/uk5njxnp/

我同意这应该简化为reduce函数,但我认为这也有助于了解如何修改你所做的工作以使其工作。

答案 3 :(得分:0)

foreach函数中的返回是针对回调而不是从addSum()函数返回。在这种情况下,Foreach回调返回将无济于事。相反,使用一些外部变量来保持总和就可以了。

下面更新的代码定义了sum函数中的变量addSum(),并向其添加了递归调用的返回值。该函数现在将返回最后计算的总和。

var testData1 = [{
  "name": "Doctors",
  "category": "Doctors",
  "subCategory": [{
    "name": "Likes",
    "category": "Likes",
    "subCategory": [{
      "name": "Visit",
      "category": "Visit",
      "subCategory": [{
        "name": "Charges",
        "category": "Charges",
        "subCategory": null,
        "val": 30
      }]
    }]
  }, {
    "name": "Dislikes",
    "category": "Dislikes",
    "subCategory": [{
      "name": "Quality",
      "category": "Quality",
      "subCategory": [{
        "name": "Appointment",
        "category": "Appointment",
        "subCategory": null,
        "val": 50
      }, {
        "name": "Care",
        "category": "Care",
        "subCategory": null,
        "val": 70
      }, {
        "name": "Attentive ",
        "category": "Attentive ",
        "subCategory": null,
        "val": 90
      }]
    }]
  }, {
    "name": "Neutral",
    "category": "Neutral",
    "subCategory": [{
      "name": "Professional ",
      "category": "Professional ",
      "subCategory": [{
        "name": "Ease",
        "category": "Ease",
        "subCategory": null,
        "val": 50
      }, {
        "name": "Competent ",
        "category": "Competent ",
        "subCategory": null,
        "val": 40
      }, {
        "name": "Availability",
        "category": "Availability",
        "subCategory": null,
        "val": 80
      }]
    }]
  }],
  "index": 6
}, {
  "name": "Service",
  "category": "Service",
  "subCategory": [{
    "name": "Likes",
    "category": "Likes",
    "subCategory": [{
      "name": "Environment",
      "category": "Environment",
      "subCategory": [{
        "name": "Professionalism ",
        "category": "Professionalism ",
        "subCategory": null,
        "val": 50
      }, {
        "name": "Room",
        "category": "Room",
        "subCategory": null,
        "val": 30
      }, {
        "name": "Parking",
        "category": "Parking",
        "subCategory": null,
        "val": 20
      }]
    }, {
      "name": "Availability",
      "category": "Availability",
      "subCategory": [{
        "name": "Competent ",
        "category": "Competent ",
        "subCategory": null,
        "val": 30
      }]
    }]
  }, {
    "name": "Dislikes",
    "category": "Dislikes",
    "subCategory": [{
      "name": "Management",
      "category": "Management",
      "subCategory": [{
        "name": "Staff",
        "category": "Staff",
        "subCategory": null,
        "val": 50
      }, {
        "name": "Operations",
        "category": "Operations",
        "subCategory": null,
        "val": 70
      }]
    }, {
      "name": "Nurses",
      "category": "Nurses",
      "subCategory": [{
        "name": "Medicine",
        "category": "Medicine",
        "subCategory": null,
        "val": 30
      }]
    }]
  }, {
    "name": "Neutral",
    "category": "Neutral",
    "subCategory": [{
      "name": "Serving",
      "category": "Serving",
      "subCategory": [{
        "name": "Took long time",
        "category": "Took long time",
        "subCategory": null,
        "val": 50
      }, {
        "name": "Rude",
        "category": "Rude",
        "subCategory": null,
        "val": 40
      }, {
        "name": "Seated",
        "category": "Seated",
        "subCategory": null,
        "val": 80
      }]
    }]
  }],
  "index": 16
}];

function addSum(data) {
   sum = 0; 
  data.forEach(function(d, index) {
    if (Array.isArray(d.subCategory)) {
      sum += (0 + addSum(d.subCategory));

    } else {

      document.write('<pre>' + JSON.stringify(d.val, 0, 4) + '</pre>');
      sum += d.val;
    }
  });

  return sum;
}
var sum1 = addSum(testData1);
alert(sum1);