如何对 JavaScript 对象的值求和?

IT技术 javascript object javascript-objects
2021-02-01 08:29:13

我想对一个对象的值求和。

我已经习惯了 python 的位置:

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

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

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)

我是否遗漏了任何明显的东西,或者这就是它的方式?

6个回答

可以这么简单:

const sumValues = obj => Object.values(obj).reduce((a, b) => a + b);

引用 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

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

@Blender 如果您想使用任何新的 ECMAScript 功能并仍然支持旧浏览器,则无论如何您都需要使用 Babel 此外,如果有人在 2 年后访问这个问题,那么现代浏览器可能会实施Object.values()到那个时候。
2021-03-15 08:29:13
@Cerbrus 我假设该对象中的所有值都是数字。
2021-03-15 08:29:13
这需要你拉一个60K库只是Object.values(),其将与被polyfilledfor上除了火狐浏览器的每个循环。即使没有 polyfill,for对我来说它也比常规循环慢 4 倍
2021-03-24 08:29:13
接受的答案具有非常相似的方法,但传递给的函数reduce似乎更万无一失。你是不是故意省略了解析?
2021-03-28 08:29:13
@Blender 看来我是对的——一年半过去了,Object.values()所有现代浏览器都支持
2021-04-05 08:29:13

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

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 );


为了好玩,这里是另一个使用Object.keys()and 的实现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)}`);

但这似乎要慢得多:jsperf.com

出色的工作突出了解决方案之间的性能差异。虽然Object.keys().reduce看起来更优雅,但速度慢了 60%。
2021-03-20 08:29:13
不客气
2021-03-22 08:29:13
返回 sum + parseFloat( obj[key] || 0) 来检查 falsey 或 null /blank 值
2021-04-10 08:29:13

如果您使用的是 lodash,则可以执行以下操作

_.sum(_.values({ 'a': 1 , 'b': 2 , 'c':3 })) 
我认为 JS 将值视为字符串。所以答案应该是“123”而不是“6”。如果我错了,请纠正我。
2021-04-11 08:29:13

常规for循环非常简洁:

var total = 0;

for (var property in object) {
    total += object[property];
}

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

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

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

console.log(Object.values(object1).reduce((a, b) => a + b, 0));