Me gustaría sumar los valores de un objeto.
Estoy acostumbrado a Python donde solo estaría:
sample = { 'a': 1 , 'b': 2 , 'c':3 };
summed = sum(sample.itervalues())
El siguiente código funciona, pero es mucho código:
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)
¿Me estoy perdiendo algo obvio o es así?
javascript
object
javascript-objects
Jonathan Vanasco
fuente
fuente
Object.keys().reduce
aspecto es mucho más elegante, es un 60% más lento.Puede ser tan simple como eso:
const sumValues = obj => Object.values(obj).reduce((a, b) => a + b);
Citando MDN:
desde
Object.values()
MDNdesde
Array.prototype.reduce()
MDNPuedes usar esta función así:
sumValues({a: 4, b: 6, c: -5, d: 0}); // gives 5
Tenga en cuenta que este código utiliza algunas funciones de ECMAScript que no son compatibles con algunos navegadores más antiguos (como IE). Es posible que deba usar Babel para compilar su código.
fuente
Object.values()
, que se rellenará con unfor
bucle en todos los navegadores, además de Firefox. Incluso sin un polyfill, es 4 veces más lento que unfor
bucle normal para mí.Object.values()
hasta ese momento.reduce
parece un poco más infalible. ¿Dejó de lado el análisis a propósito?Object.values()
es compatible con todos los navegadores modernos .Si está usando lodash, puede hacer algo como
_.sum(_.values({ 'a': 1 , 'b': 2 , 'c':3 }))
fuente
Un
for
bucle regular es bastante conciso:var total = 0; for (var property in object) { total += object[property]; }
Es posible que deba agregarlo
object.hasOwnProperty
si modificó el prototipo.fuente
Honestamente, dados nuestros "tiempos modernos", optaría por un enfoque de programación funcional siempre que sea posible, así:
const sumValues = (obj) => Object.keys(obj).reduce((acc, value) => acc + obj[value], 0);
Nuestro acumulador
acc
, comenzando con un valor de 0, está acumulando todos los valores en bucle de nuestro objeto. Esto tiene el beneficio adicional de no depender de ninguna variable interna o externa; es una función constante, por lo que no se sobrescribirá accidentalmente ... ¡gana para ES2015!fuente
¿Alguna razón por la que no estás usando un simple
for...in
bucle?var sample = { a: 1 , b: 2 , c:3 }; var summed = 0; for (var key in sample) { summed += sample[key]; };
http://jsfiddle.net/vZhXs/
fuente
Ahora puede hacer uso de la
reduce
función y obtener la suma.const object1 = { 'a': 1 , 'b': 2 , 'c':3 } console.log(Object.values(object1).reduce((a, b) => a + b, 0));
fuente
Llego un poco tarde a la fiesta, sin embargo, si necesita una solución más robusta y flexible, aquí está mi contribución. Si desea sumar solo una propiedad específica en un combo de objeto / matriz anidado, así como realizar otros métodos agregados, aquí hay una pequeña función que he estado usando en un proyecto de 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; }
Es recursivo, no es ES6 y debería funcionar en la mayoría de los navegadores semi-modernos. Lo usas así:
const onlineCount = aggregateProperty(this.props.contacts, 'online', 'count');
Desglose de parámetros:
obj =
propiedad de un objeto o de una matriz = la propiedad dentro de los objetos / matrices anidados que desea realizar el método
agregado en agregado = el método agregado (suma, mínimo, máximo o recuento)
superficial = se puede establecer en verdadero / falso o un valor numérico
profundidad = debe dejarse nulo o indefinido (se usa para rastrear las devoluciones de llamada recursivas posteriores)
Shallow se puede utilizar para mejorar el rendimiento si sabe que no necesitará buscar datos profundamente anidados. Por ejemplo, si tuviera la siguiente matriz:
[ { id: 1, otherData: { ... }, valueToBeTotaled: ? }, { id: 2, otherData: { ... }, valueToBeTotaled: ? }, { id: 3, otherData: { ... }, valueToBeTotaled: ? }, ... ]
Si desea evitar recorrer la propiedad otherData ya que el valor que va a agregar no está anidado tan profundamente, puede establecer shallow en verdadero.
fuente
Usar 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
fuente
let prices = { "apple": 100, "banana": 300, "orange": 250 }; let sum = 0; for (let price of Object.values(prices)) { sum += price; } alert(sum)
fuente
Encontré esta solución de @jbabey mientras intentaba resolver un problema similar. Con una pequeña modificación, lo hice bien. En mi caso, las claves de objeto son números (489) y cadenas ("489"). Por lo tanto, para resolver esto, cada clave se analiza. El siguiente código funciona:
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);
fuente
Un forro ramda one:
import { compose, sum, values, } from 'ramda' export const sumValues = compose(sum, values);
Utilizar:
const summed = sumValues({ 'a': 1 , 'b': 2 , 'c':3 });
fuente
Podemos repetir objeto utilizando en la palabra clave y puede realizar cualquier operación aritmética.
// 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);
fuente
Sume el valor de la clave del objeto analizando Integer. Conversión de formato de cadena a entero y suma de valores
var obj = { pay: 22 }; obj.pay; console.log(obj.pay); var x = parseInt(obj.pay); console.log(x + 20);
fuente