如何遍历含数组的对象求和并按最新年份排序?求更优方案
Hey there! Let's refine your code to be cleaner, more efficient, and fix the sorting issue in your current implementation. Your goal is to generate a year-sorted (newest to oldest) object with total dividend values per year, so let's break down a better approach:
The Optimized Solution
const dividendsYears = { 1976: [ {date: "1976-05-10", value: "0.00062"}, {date: "1976-07-16", value: "0.00062"}, {date: "1976-10-21", value: "0.00062"} ], 1977: [ {date: "1977-02-14", value: "0.00062"}, {date: "1977-05-12", value: "0.00123"}, {date: "1977-07-19", value: "0.00123"}, {date: "1977-10-18", value: "0.00123"} ], 1978: [ {date: "1978-02-14", value: "0.00123"}, {date: "1978-05-16", value: "0.00222"}, {date: "1978-07-19", value: "0.00222"}, {date: "1978-10-26", value: "0.00222"} ] }; const totalDividendsPerYear = Object.fromEntries( // First, convert the object to [year, entries] pairs and sort years descending Object.entries(dividendsYears) .sort(([yearA], [yearB]) => Number(yearB) - Number(yearA)) // Then calculate the total for each year using reduce .map(([year, dividendEntries]) => [ year, dividendEntries.reduce((total, entry) => total + Number(entry.value), 0) ]) ); console.log(totalDividendsPerYear); // Output: { '1978': 0.00789, '1977': 0.0043100000000000005, '1976': 0.00186 }
What Makes This Better?
- Cleaner Chain of Operations: We combine sorting, sum calculation, and object creation into a single flow, avoiding unnecessary intermediate variables like your original
totalDividendsPerYearandsortRecentDate. - Reliable Sorting: Your original
reverse()approach isn't guaranteed to work (object key order is insertion order in ES6+, but reversing that doesn't account for unordered keys in older environments or non-sequential years). This solution explicitly sorts years numerically in descending order. - Functional Style with
reduce: Usingreducefor summation is more idiomatic than aforEachloop with a mutablesumvariable—it's concise and avoids side effects.
Bonus: Fixing Floating-Point Precision
If you want to clean up those long decimal results (like 0.0043100000000000005), you can round the total to a fixed number of decimal places:
// Option 1: Fixed decimal places (returns string) dividendEntries.reduce((total, entry) => total + Number(entry.value), 0).toFixed(6) // Option 2: Precision-safe rounding (returns number) Math.round((dividendEntries.reduce((total, entry) => total + Number(entry.value), 0)) * 1e6) / 1e6
内容的提问来源于stack exchange,提问作者kr3w4
相关产品推荐
相关产品推荐

