Saya ingin menjumlahkan nilai suatu objek.
Saya terbiasa dengan python di mana itu hanya akan:
sample = { 'a': 1 , 'b': 2 , 'c':3 };
summed = sum(sample.itervalues())
Kode berikut berfungsi, tetapi banyak kode:
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)
Apakah saya melewatkan sesuatu yang jelas, atau apakah memang begini adanya?
javascript
object
javascript-objects
Jonathan Vanasco
sumber
sumber
Object.keys().reduce
tampilannya jauh lebih elegan, ini 60% lebih lambat.Ini bisa sesederhana itu:
const sumValues = obj => Object.values(obj).reduce((a, b) => a + b);
Mengutip MDN:
dari
Object.values()
di MDNdari
Array.prototype.reduce()
di MDNAnda dapat menggunakan fungsi ini seperti itu:
sumValues({a: 4, b: 6, c: -5, d: 0}); // gives 5
Perhatikan bahwa kode ini menggunakan beberapa fitur ECMAScript yang tidak didukung oleh beberapa browser lama (seperti IE). Anda mungkin perlu menggunakan Babel untuk mengompilasi kode Anda.
sumber
Object.values()
, yang akan diisi denganfor
loop di setiap browser selain Firefox. Bahkan tanpa polyfill, ini 4x lebih lambat darifor
loop biasa bagi saya.Object.values()
hingga saat itu.reduce
tampaknya sedikit lebih mudah dilakukan. Apakah Anda sengaja mengabaikan penguraian?Object.values()
didukung oleh semua browser modern .Jika Anda menggunakan lodash, Anda dapat melakukan sesuatu seperti
_.sum(_.values({ 'a': 1 , 'b': 2 , 'c':3 }))
sumber
Putaran biasa
for
cukup ringkas:var total = 0; for (var property in object) { total += object[property]; }
Anda mungkin harus menambahkan
object.hasOwnProperty
jika Anda memodifikasi prototipe.sumber
Sejujurnya, mengingat "zaman modern" kami, saya akan menggunakan pendekatan pemrograman fungsional bila memungkinkan, seperti:
const sumValues = (obj) => Object.keys(obj).reduce((acc, value) => acc + obj[value], 0);
Akumulator kita
acc
, dimulai dengan nilai 0, mengumpulkan semua nilai loop dari objek kita. Ini memiliki keuntungan tambahan karena tidak bergantung pada variabel internal atau eksternal; ini adalah fungsi konstan sehingga tidak akan tertimpa secara tidak sengaja ... menang untuk ES2015!sumber
Sekarang Anda dapat menggunakan
reduce
fungsi dan mendapatkan jumlahnya.const object1 = { 'a': 1 , 'b': 2 , 'c':3 } console.log(Object.values(object1).reduce((a, b) => a + b, 0));
sumber
Adakah alasan Anda tidak hanya menggunakan
for...in
loop sederhana ?var sample = { a: 1 , b: 2 , c:3 }; var summed = 0; for (var key in sample) { summed += sample[key]; };
http://jsfiddle.net/vZhXs/
sumber
Saya agak terlambat ke pesta, namun, jika Anda memerlukan solusi yang lebih kuat dan fleksibel, inilah kontribusi saya. Jika Anda hanya ingin menjumlahkan properti tertentu dalam kombo objek / array bersarang, serta melakukan metode agregat lainnya, maka berikut adalah fungsi kecil yang telah saya gunakan pada proyek 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; }
Ini rekursif, non ES6, dan seharusnya berfungsi di sebagian besar browser semi-modern. Anda menggunakannya seperti ini:
const onlineCount = aggregateProperty(this.props.contacts, 'online', 'count');
Rincian parameter:
obj = salah satu objek atau
properti array = properti dalam objek / array bertingkat yang ingin Anda lakukan metode
agregat pada agregat = metode agregat (jumlah, min, maks, atau jumlah)
shallow = dapat disetel ke true / false atau nilai numerik
depth = harus dibiarkan nol atau tidak ditentukan (digunakan untuk melacak callback rekursif berikutnya)
Shallow dapat digunakan untuk meningkatkan kinerja jika Anda tahu bahwa Anda tidak perlu mencari data yang sangat bertingkat. Misalnya jika Anda memiliki array berikut:
[ { id: 1, otherData: { ... }, valueToBeTotaled: ? }, { id: 2, otherData: { ... }, valueToBeTotaled: ? }, { id: 3, otherData: { ... }, valueToBeTotaled: ? }, ... ]
Jika Anda ingin menghindari perulangan melalui properti otherData karena nilai yang akan Anda gabungkan tidak bertumpuk sedalam itu, Anda dapat menyetel dangkal ke true.
sumber
Gunakan 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
sumber
let prices = { "apple": 100, "banana": 300, "orange": 250 }; let sum = 0; for (let price of Object.values(prices)) { sum += price; } alert(sum)
sumber
Saya menemukan solusi ini dari @jbabey ketika mencoba memecahkan masalah serupa. Dengan sedikit modifikasi, saya benar. Dalam kasus saya, kunci objek adalah angka (489) dan string ("489"). Karenanya untuk menyelesaikan ini, setiap kunci diurai. Kode berikut berfungsi:
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);
sumber
Sebuah ramda one liner:
import { compose, sum, values, } from 'ramda' export const sumValues = compose(sum, values);
Menggunakan:
const summed = sumValues({ 'a': 1 , 'b': 2 , 'c':3 });
sumber
Kita dapat melakukan iterasi objek menggunakan kata kunci dalam dan dapat melakukan operasi aritmatika apa pun.
// 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);
sumber
Jumlahkan nilai kunci objek dengan parse Integer. Mengonversi format string menjadi integer dan menjumlahkan nilainya
var obj = { pay: 22 }; obj.pay; console.log(obj.pay); var x = parseInt(obj.pay); console.log(x + 20);
sumber