如何总结一个JavaScript对象的值是多少?(How to sum the values of

2019-09-02 07:52发布

我想总结对象的值。

我已经习惯了蟒蛇的地方也只是:

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)

我失去了什么明显的,或者这只是事情是这样的?

Answer 1:

你可以把它们都放在一个函数:

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



Answer 2:

它可以是如此简单:

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

引用MDN:

所述Object.values()方法返回在给定对象的自己的可枚举的属性值的数组,在相同的顺序,通过提供一种for...in环(不同之处在于一个用于-in循环枚举在原型侧链性质为好)。

Object.values()上MDN

reduce()方法应用于对一个储液器的功能和所述阵列的每一值(从左到右),以将其降低到一个值。

Array.prototype.reduce()上MDN

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

sumValues({a: 4, b: 6, c: -5, d: 0}); // gives 5

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



Answer 3:

有规律for循环是很简洁:

var total = 0;

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

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



Answer 4:

如果您使用lodash你可以这样做

_.sum(_.values({ 'a': 1 , 'b': 2 , 'c':3 })) 


Answer 5:

你不只是使用简单的任何理由for...in循环?

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

for (var key in sample) {
    summed += sample[key];
};

http://jsfiddle.net/vZhXs/



Answer 6:

老实说,我们给予“摩登时代”我会用一个函数式编程的方法去只要有可能,就像这样:

const sumValues = (obj) => Object.keys(obj).reduce((acc, value) => acc + obj[value], 0);

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



Answer 7:

我有点迟到的聚会,但是,如果你需要一个更强大和灵活的解决方案,然后这里是我的贡献。 如果要总结只有一个特定的属性在一个嵌套的对象/阵列组合,以及执行其他聚合方法,那么这里就是我一直在使用一个阵营项目的小功能:

var aggregateProperty = function(obj, property, aggregate, shallow, depth) {
    //return aggregated value of a specific property within an object (or array of objects..)

    if ((typeof obj !== 'object' && typeof obj !== 'array') || !property) {
        return;
    }

    obj = JSON.parse(JSON.stringify(obj)); //an ugly way of copying the data object instead of pointing to its reference (so the original data remains unaffected)
    const validAggregates = [ 'sum', 'min', 'max', 'count' ];
    aggregate = (validAggregates.indexOf(aggregate.toLowerCase()) !== -1 ? aggregate.toLowerCase() : 'sum'); //default to sum

    //default to false (if true, only searches (n) levels deep ignoring deeply nested data)
    if (shallow === true) {
        shallow = 2;
    } else if (isNaN(shallow) || shallow < 2) {
        shallow = false;
    }

    if (isNaN(depth)) {
        depth = 1; //how far down the rabbit hole have we travelled?
    }

    var value = ((aggregate == 'min' || aggregate == 'max') ? null : 0);
    for (var prop in obj) {
        if (!obj.hasOwnProperty(prop)) {
            continue;
        }

        var propValue = obj[prop];
        var nested = (typeof propValue === 'object' || typeof propValue === 'array');
        if (nested) {
            //the property is an object or an array

            if (prop == property && aggregate == 'count') {
                value++;
            }

            if (shallow === false || depth < shallow) {
                propValue = aggregateProperty(propValue, property, aggregate, shallow, depth+1); //recursively aggregate nested objects and arrays
            } else {
                continue; //skip this property
            }
        }

        //aggregate the properties value based on the selected aggregation method
        if ((prop == property || nested) && propValue) {
            switch(aggregate) {
                case 'sum':
                    if (!isNaN(propValue)) {
                        value += propValue;
                    }
                    break;
                case 'min':
                    if ((propValue < value) || !value) {
                        value = propValue;
                    }
                    break;
                case 'max':
                    if ((propValue > value) || !value) {
                        value = propValue;
                    }
                    break;
                case 'count':
                    if (propValue) {
                        if (nested) {
                            value += propValue;
                        } else {
                            value++;
                        }
                    }
                    break;
            }
        }
    }

    return value;
}

这是递归的,非ES6,它应该在大多数半现代的浏览器。 您可以使用这样的:

const onlineCount = aggregateProperty(this.props.contacts, 'online', 'count');

参数明细:

OBJ =任一物体或阵列
属性 =嵌套对象/数组内的属性要上执行聚合方法
骨料 =聚合方法(总和,最小值,最大值,或计数)
=可以被设置为真/假或数值
深度 =应保留为空的或未定义的(它被用于跟踪后续递归回调)

浅层可以使用,如果你知道,你不会需要搜索深度嵌套的数据,以提高性能。 例如,如果你有以下阵列:

[
    {
        id: 1,
        otherData: { ... },
        valueToBeTotaled: ?
    },
    {
        id: 2,
        otherData: { ... },
        valueToBeTotaled: ?
    },
    {
        id: 3,
        otherData: { ... },
        valueToBeTotaled: ?
    },
    ...
]

如果你想避免通过,因为价值你要成为otherData财产循环聚集不嵌套在深,你可以设置得较浅为true。



Answer 8:

我碰到这个解决方案从@jbabey同时试图解决一个类似的问题。 随着一点点的改变,我得到了它的权利。 在我的情况下,对象键的数字(489)和字符串(“489”)。 因此,为了解决这个问题,每个键是解析。 下面的代码工作:

var array = {"nR": 22, "nH": 7, "totB": "2761", "nSR": 16, "htRb": "91981"}
var parskey = 0;
for (var key in array) {
    parskey = parseInt(array[key]);
    sum += parskey;
};
return(sum);


Answer 9:

一个ramda一个班轮:

import {
 compose, 
 sum,
 values,
} from 'ramda'

export const sumValues = compose(sum, values);

使用: const summed = sumValues({ 'a': 1 , 'b': 2 , 'c':3 });



文章来源: How to sum the values of a JavaScript object?