如何求和JavaScript对象的值?

Jon*_*sco 66 javascript object javascript-objects

我想总结一个对象的值.

我习惯了python,它只会是:

sample = { 'a': 1 , 'b': 2 , 'c':3 };
summed =  sum(sample.itervalues())     
Run Code Online (Sandbox Code Playgroud)

以下代码有效,但它是很多代码:

function obj_values(object) {
  var results = [];
  for (var property in object)
    results.push(object[property]);
  return results;
}

function list_sum( list ){
  return list.reduce(function(previousValue, currentValue, index, array){
      return previousValue + currentValue;
  });
}

function object_values_sum( obj ){
  return list_sum(obj_values(obj));
}

var sample = { a: 1 , b: 2 , c:3 };
var summed =  list_sum(obj_values(a));
var summed =  object_values_sum(a)
Run Code Online (Sandbox Code Playgroud)

我错过了什么明显的,或者这只是它的方式?

Mic*_*ski 77

它可以很简单:

const sumValues = obj => Object.values(obj).reduce((a, b) => a + b);
Run Code Online (Sandbox Code Playgroud)

引用MDN:

Object.values()方法返回给定对象自己的可枚举属性值的数组,其顺序与for...in循环提供的顺序相同(不同之处在于for-in循环也枚举原型链中的属性).

来自Object.values()MDN

reduce()方法对累加器和数组的每个值(从左到右)应用函数以将其减少为单个值.

来自Array.prototype.reduce()MDN

您可以像这样使用此功能:

sumValues({a: 4, b: 6, c: -5, d: 0}); // gives 5
Run Code Online (Sandbox Code Playgroud)

请注意,此代码使用一些较旧的浏览器(如IE)不支持的ECMAScript功能.您可能需要使用Babel来编译代码.

  • @Blender如果你想使用*any*的新ECMAScript功能并仍然支持旧浏览器,你还是需要使用Babel.此外,如果有人在2年后访问此问题,现代浏览器可能会实现`Object.values()`直到那时为止. (8认同)
  • @Blender看来我是对的 - 一年半过去了,所有现代浏览器都支持[`Object.values()`(https://caniuse.com/#feat=object-values). (8认同)
  • 这需要你拉一个60K的库**才能得到`Object.values()`,除了Firefox之外,它将在每个浏览器上用`for`循环进行填充.即使没有polyfill,它比我常规的'for`循环慢4倍. (3认同)

Sir*_*rko 58

你可以把它全部放在一个函数中:

function sum( obj ) {
  var sum = 0;
  for( var el in obj ) {
    if( obj.hasOwnProperty( el ) ) {
      sum += parseFloat( obj[el] );
    }
  }
  return sum;
}
    
var sample = { a: 1 , b: 2 , c:3 };
var summed = sum( sample );
console.log( "sum: "+summed );
Run Code Online (Sandbox Code Playgroud)


为了好玩,这里是使用Object.keys()和的另一个实现Array.reduce()(浏览器支持不应该是一个大问题):

function sum(obj) {
  return Object.keys(obj).reduce((sum,key)=>sum+parseFloat(obj[key]||0),0);
}
let sample = { a: 1 , b: 2 , c:3 };

console.log(`sum:${sum(sample)}`);
Run Code Online (Sandbox Code Playgroud)

但这似乎慢得多:jsperf.com

  • 出色地突出了解决方案之间的性能差异。虽然“Object.keys().reduce”看起来更加优雅,但速度却慢了 60%。 (2认同)

Ble*_*der 18

常规for循环非常简洁:

var total = 0;

for (var property in object) {
    total += object[property];
}
Run Code Online (Sandbox Code Playgroud)

object.hasOwnProperty如果修改了原型,则可能需要添加.


Leo*_*eon 18

如果你正在使用lodash,你可以做类似的事情

_.sum(_.values({ 'a': 1 , 'b': 2 , 'c':3 })) 
Run Code Online (Sandbox Code Playgroud)


jba*_*bey 12

你不是只使用一个简单的for...in循环的原因吗?

var sample = { a: 1 , b: 2 , c:3 };
var summed = 0;

for (var key in sample) {
    summed += sample[key];
};
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/vZhXs/


Ric*_*ães 9

老实说,鉴于我们的"现代",我会尽可能采用函数式编程方法,如下所示:

const sumValues = (obj) => Object.keys(obj).reduce((acc, value) => acc + obj[value], 0);
Run Code Online (Sandbox Code Playgroud)

我们的累加器acc,从值0开始,正在累积对象的所有循环值.这具有不依赖于任何内部或外部变量的额外好处; 它是一个恒定的功能,因此不会被意外覆盖......赢得ES2015!


Kri*_* PC 5

现在,您可以使用reduce函数并获取总和。

const object1 = { 'a': 1 , 'b': 2 , 'c':3 }

console.log(Object.values(object1).reduce((a, b) => a + b, 0));
Run Code Online (Sandbox Code Playgroud)