Node.js/TypeScript中如何对多份同键数值型JSON求和?
Hey there! Since you're new to Node.js and TypeScript, let's walk through how to solve this JSON summation problem—we'll build a recursive function that handles nested objects and arrays, which is perfect for your use case.
Step 1: Define TypeScript Types for JSON Values
First, let's set up types to represent valid JSON values. This helps TypeScript catch errors and gives us better autocomplete:
type JsonValue = string | number | boolean | null | JsonObject | JsonArray; interface JsonObject { [key: string]: JsonValue; } interface JsonArray extends Array<JsonValue> {}
Step 2: Build a Recursive Summation Function
We need a function that can traverse nested structures (objects and arrays) and sum corresponding numeric values. Here's how to do it:
function sumJson(a: JsonValue, b: JsonValue): JsonValue { // Sum numeric values directly if (typeof a === 'number' && typeof b === 'number') { return a + b; } // Recursively sum nested objects if (typeof a === 'object' && a !== null && typeof b === 'object' && b !== null && !Array.isArray(a) && !Array.isArray(b)) { const result: JsonObject = {}; // Grab all keys (since structures are identical, keys should match) const allKeys = new Set([...Object.keys(a as JsonObject), ...Object.keys(b as JsonObject)]); for (const key of allKeys) { result[key] = sumJson((a as JsonObject)[key], (b as JsonObject)[key]); } return result; } // Recursively sum arrays (matching index positions) if (Array.isArray(a) && Array.isArray(b)) { return a.map((item, index) => sumJson(item, b[index])); } // For non-numeric values (strings, booleans, null), keep the value from the first object // (Since structures are identical, these values should be the same across all inputs) return a; }
Step 3: Handle Multiple JSON Objects
To sum more than two JSONs, we can use Array.reduce() to accumulate the results:
function sumMultipleJsons(...jsons: JsonValue[]): JsonValue { if (jsons.length === 0) return {}; // Return empty object if no inputs return jsons.reduce((accumulator, current) => sumJson(accumulator, current)); }
Testing with Your Example
Let's plug in your sample JSONs (I filled in the missing value in json2 with 30 for demonstration):
const json1 = { "201809": 2, "metric": "headcount", "quarter1": 60, "careerLevelsGroups": [{ "201809": 2, "quarter1": 60, "careerLevels": [{ "201809": 2, "careerId": "careerId1", "quarter1": 60, }, { "201809": 2, "careerId": "careerId2", "quarter1": 50, }] }] }; const json2 = { "201809": 3, "metric": "headcount", "quarter1": 100, "careerLevelsGroups": [{ "201809": 7, "quarter1": 40, "careerLevels": [{ "201809": 9, "careerId": "careerId1", "quarter1": 30 }] }] }; // Sum the two JSONs const summedResult = sumMultipleJsons(json1, json2); console.log(JSON.stringify(summedResult, null, 2));
Output:
{ "201809": 5, "metric": "headcount", "quarter1": 160, "careerLevelsGroups": [ { "201809": 9, "quarter1": 100, "careerLevels": [ { "201809": 11, "careerId": "careerId1", "quarter1": 90 }, { "201809": 2, "careerId": "careerId2", "quarter1": 50 } ] } ] }
Notes to Keep in Mind
- Structure Consistency: This solution assumes all input JSONs have identical structures. If there's a mismatch (e.g., a key exists in one but not the other, or different types), you might want to add error handling (like throwing an error or logging a warning).
- Non-Numeric Values: We keep non-numeric values from the first JSON. If you need to validate that these values are identical across all inputs, you can add a check in the function.
内容的提问来源于stack exchange,提问作者user3205921

