我想总结一个对象的值。
我习惯了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)
我错过了什么明显的,或者这只是它的方式?
答案 0 :(得分:66)
可以这么简单:
const sumValues = obj => Object.values(obj).reduce((a, b) => a + b);
引用MDN:
来自
Object.values()
方法返回给定对象自己的可枚举属性值的数组,其顺序与for...in
循环提供的顺序相同(不同之处在于for-in循环也枚举了原型链中的属性。
Object.values()
on MDN 的
来自reduce()
方法对累加器和数组的每个值(从左到右)应用函数以将其减少为单个值。Array.prototype.reduce()
on MDN
您可以像这样使用此功能: 请注意,此代码使用某些旧版浏览器(如IE)不支持的某些ECMAScript功能。您可能需要使用Babel来编译代码。sumValues({a: 4, b: 6, c: -5, d: 0}); // gives 5
答案 1 :(得分:55)
你可以把它全部放在一个功能中:
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
答案 2 :(得分:18)
常规for
循环非常简洁:
var total = 0;
for (var property in object) {
total += object[property];
}
如果您修改了原型,则可能需要添加object.hasOwnProperty
。
答案 3 :(得分:17)
如果您正在使用lodash,则可以执行类似
的操作_.sum(_.values({ 'a': 1 , 'b': 2 , 'c':3 }))
答案 4 :(得分:11)
您是不是只使用简单的for...in
循环?
var sample = { a: 1 , b: 2 , c:3 };
var summed = 0;
for (var key in sample) {
summed += sample[key];
};
答案 5 :(得分:8)
老实说,鉴于我们的现代时代&#34;我尽可能采用函数式编程方法,如下所示:
const sumValues = (obj) => Object.keys(obj).reduce((acc, value) => acc + obj[value], 0);
我们的累加器acc
,以值0开头,正在累积对象的所有循环值。这具有不依赖于任何内部或外部变量的额外好处;它是一个不变的功能,所以它不会被意外覆盖......赢得ES2015!
答案 6 :(得分:1)
我对派对有点迟钝,但是,如果你需要一个更强大和灵活的解决方案,那么这就是我的贡献。如果你只想对嵌套对象/数组组合中的特定属性求和,以及执行其他聚合方法,那么这里是我在React项目中使用的一个小函数:
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 =对象或数组
属性 =您希望在上面执行聚合方法的嵌套对象/数组中的属性
聚合 =聚合方法(总和,最小,最大或计数)
浅 =可以设置为true / false或数值
深度 =应保留为null或未定义(用于跟踪后续的递归回调)
如果您知道不需要搜索深层嵌套数据,则可以使用浅层来增强性能。例如,如果您有以下数组:
[
{
id: 1,
otherData: { ... },
valueToBeTotaled: ?
},
{
id: 2,
otherData: { ... },
valueToBeTotaled: ?
},
{
id: 3,
otherData: { ... },
valueToBeTotaled: ?
},
...
]
如果你想避免循环遍历otherData属性,因为你要聚合的值没有深度嵌套,你可以将shallow设置为true。
答案 7 :(得分:1)
else
答案 8 :(得分:0)
我在尝试解决类似问题时遇到了来自@jbabey的解决方案。经过一点修改,我做对了。在我的例子中,对象键是数字(489)和字符串(“489”)。因此,为了解决这个问题,每个密钥都是解析的。以下代码有效:
xd.LoadXml(IO.Files.ReadAllText(path));
答案 9 :(得分:0)
一个ramda衬纸:
import {
compose,
sum,
values,
} from 'ramda'
export const sumValues = compose(sum, values);
使用:
const summed = sumValues({ 'a': 1 , 'b': 2 , 'c':3 });
答案 10 :(得分:0)
现在,您可以使用reduce
函数来获取总和。
const object1 = { 'a': 1 , 'b': 2 , 'c':3 }
console.log(Object.values(object1).reduce((a, b) => a + b, 0));
答案 11 :(得分:0)
使用Lodash
import _ from 'Lodash';
var object_array = [{a: 1, b: 2, c: 3}, {a: 4, b: 5, c: 6}];
return _.sumBy(object_array, 'c')
// return => 9
答案 12 :(得分:0)
我们可以使用 in 关键字来迭代对象,并且可以执行任何算术运算。
// input
const sample = {
'a': 1,
'b': 2,
'c': 3
};
// var
let sum = 0;
// object iteration
for (key in sample) {
//sum
sum += (+sample[key]);
}
// result
console.log("sum:=>", sum);
答案 13 :(得分:0)
通过分析Integer求和对象键值。将字符串格式转换为整数并求和
var obj = {
pay: 22
};
obj.pay;
console.log(obj.pay);
var x = parseInt(obj.pay);
console.log(x + 20);