Tengo un objeto JSON como este, llamémoslo "testJson":
{ "property1": [{ "id": "abc", "category": "recordsCount1" }, { "id": "def", "category": "recordsCount2" } ], "property2": [{ "abc": 8, "def": 15 }, { "abc": 62, "def": 7 }, { "abc": 4, "def": 16 } ]}Quiero resumir todos los valores en los tres objetos dentro de "property2" para las propiedades "abc" y "def". Por ejemplo, para el "abc" deberíamos recibir 8 + 62 + 4 = 74 y para el "def" 15 + 16 + 7 = 38.
Hasta ahora he hecho esto con 2 ciclos for dentro de dos funciones diferentes, como esta:
function totalAbc(testJson) { var total = 0; for (var i = 0; i < testJson.property2.length; i++) { total = total + testJson.property2[i].abc; } return total; function totalDef(testJson) { var total1 = 0; for (var i = 0; i < testJson.property2.length; i++) { total1 = total1 + testJson.property2[i].def; } return total1; } var sumUpValue = totalAbc(testJson) + totalDef(testJson);Pregunta
¿Hay una mejor manera de hacerlo, por ejemplo, usando los identificadores de "propiedad1", ya que son iguales? La cuestión es que quiero evitar usar los nombres de propiedad exactos para "abc" y "def" mientras los recorro porque no son constantes y cambian según ciertos criterios.
¡Gracias por adelantado!
Bueno, escribí una función llamada total() que hace lo que tú quieres.
Paso los nombres de las propiedades y la matriz de origen a total() , y me devuelve un nuevo objeto que nombra los totales, como total( array, ['property1','property2']) me da { "property1": 77, "property2": 42 } .
Pero, dado que creo que está buscando aprender, no solo obtener la respuesta, le recomiendo leer sobre Array.reduce() , Array.map() y Object.fromEntries() .
Puede ver la forma en que los usé para resolver el problema a continuación. Una vez que haya leído acerca de las funciones, espero que mi respuesta tenga sentido. (El uso de estas funciones de matriz es un desafío, así que tenga paciencia para tratar de dominarlas).
const testJSON = { "property1": [{ "id": "abc", "category": "recordsCount1" }, { "id": "def", "category": "recordsCount2" } ], "property2": [{ "abc": 8, "def": 15 }, { "abc": 62, "def": 7 }, { "abc": 4, "def": 16 } ] } function total( array, properties ) { const entries = properties.map( propertyName => [ propertyName, array.reduce( ( sum, entry ) => sum + entry[ propertyName ], 0 ) ] ); return Object.fromEntries( entries ); } console.log( total( testJSON.property2, [ 'abc', 'def' ] ) );Si sus objetos pueden tener otras propiedades que no están relacionadas con la suma que desea hacer, entonces sí, debe usar property1 :
let data = {"property1": [{"id": "abc", "category": "recordsCount1"}, {"id": "def","category": "recordsCount2"}],"property2": [{"abc": 8,"def": 15}, {"abc": 62,"def": 7}, {"abc": 4,"def": 16}]}; let keys = data.property1.map(o => o.id); let sum = data.property2.reduce((sum, o) => keys.reduce((sum, key) => sum + o[key]??0, sum), 0); console.log(sum);Array.reduce puede resolver fácilmente su problema.
const input = { "property1": [{ "id": "abc", "category": "recordsCount1" }, { "id": "def", "category": "recordsCount2" }], "property2": [{ "abc": 8, "def": 15 }, { "abc": 62, "def": 7 }, { "abc": 4, "def": 16 }] }; var sumProps = input.property2.reduce((acc, item) => { for (prop in item) { if (prop in acc) { acc[prop] += item[prop]; } else { acc[prop] = item[prop]; } } return acc; }, {}); console.log(sumProps); var totalSum = 0; for (item in sumProps) { totalSum += sumProps[item]; } console.log(totalSum);