如何在Array reduce求和时排除指定数组中的账户?
问题
现有存储账户余额的对象和计算余额总和的函数,当前通过Array.reduce方法计算所有账户余额总和得到流通供应量:
const _balances = { "0x000000000": 100, "0xCONTRACTOR": 200, "0xALICE": 300, "0xBOB": 400, "0xCHARLIE": 500, }; function circulatingSupply() { // 当前流通中的代币总数,由各账户持有 return Object.values(_balances).reduce((a, b) => a + b, 0); }
现在有一个_ignore数组,其中的账户不应被纳入求和范围:
const _ignore = [ "0x000000000", "0xCONTRACTOR", ];
如何修改实现?(本人对Array.reduce方法不太熟悉)
解决方案
方法1:先过滤再求和(直观易懂)
先把对象转成键值对数组,过滤掉忽略的账户后再提取余额求和,逻辑清晰,适合新手理解:
const _balances = { "0x000000000": 100, "0xCONTRACTOR": 200, "0xALICE": 300, "0xBOB": 400, "0xCHARLIE": 500, }; const _ignore = [ "0x000000000", "0xCONTRACTOR", ]; function circulatingSupply() { return Object.entries(_balances) // 过滤掉忽略列表里的账户 .filter(([account]) => !_ignore.includes(account)) // 提取剩余账户的余额 .map(([_, balance]) => balance) // 累加余额总和 .reduce((total, current) => total + current, 0); }
步骤说明:
Object.entries(_balances):将余额对象转换为[账户地址, 余额]格式的二维数组,比如[["0x000000000", 100], ...]filter:筛选出不在_ignore列表中的账户项map:把筛选后的键值对数组转换为仅包含余额的数组reduce:和原逻辑一致,将余额数组累加求和,0是求和的初始值
方法2:在reduce内直接判断(更高效)
省去中间的map步骤,直接在reduce的回调里判断是否忽略当前账户,减少一次数组遍历:
function circulatingSupply() { return Object.entries(_balances).reduce((total, [account, balance]) => { // 仅当账户不在忽略列表时,累加余额 if (!_ignore.includes(account)) { total += balance; } // 必须返回更新后的总和,供下一次迭代使用 return total; }, 0); // 初始总和设为0 }
步骤说明:
reduce的回调函数接收两个核心参数:total(当前累加的总和)、当前迭代的[account, balance]键值对- 每次迭代判断账户是否在忽略列表,不在则将余额加到
total上 - 无论是否累加,都要返回
total,确保下一次迭代能拿到最新的总和
性能优化(针对大量忽略账户)
如果_ignore数组包含大量账户,includes的查找效率较低(O(n)),可以将数组转为Set,把查找效率提升到O(1):
// 提前将忽略列表转为Set const ignoreSet = new Set(_ignore); function circulatingSupply() { return Object.entries(_balances).reduce((total, [account, balance]) => { if (!ignoreSet.has(account)) { total += balance; } return total; }, 0); }
内容的提问来源于stack exchange,提问作者suchislife801
相关产品推荐
相关产品推荐

