数组值映射分配问题:将发送方数值匹配到接收方数组
数值分配逻辑修正问题
我有两个数组,发送方数组元素包含value和sender字段,接收方数组元素包含value和recipient字段。需要按照以下规则将发送方数值分配给接收方:
- 若发送方元素数值小于当前接收方剩余需求,则全部分配;
- 若发送方元素数值大于当前接收方剩余需求,则先填满该接收方需求,剩余数值分配给下一个接收方。
我使用BigNumber.js处理数值精度,formatUnits函数格式化数值。现有代码无法得到预期输出,请求修正。
发送方数组
const firstArray =[ { value: 0.001, sender: "one"}, { value: 0.01, sender: "two"}, { value: 0.1, sender: "three"}, { value: 3.0, sender: "four"}, { value: 0.002, sender: "five"}, { value: 0.0003, sender: "six"}, { value: 5.0, sender: "seven"} ]
接收方数组
const secondArray = [ { value: 0.5, recipient: "a"}, { value: 3.5, recipient: "b"}, { value: 4.2133, recipient: "c"} ]
预期输出
const thirdArray = [ {sender : "one", receiver : "a", amount : 0.001}, {sender : "two", receiver : "a", amount : 0.01}, {sender : "three", receiver : "a", amount : 0.1}, {sender : "four", receiver : "a", amount : 0.389}, {sender : "four", receiver : "b", amount : 2.611}, {sender : "five", receiver : "b", amount : 0.002}, {sender : "six", receiver : "b", amount : 0.0003}, {sender : "seven", receiver : "b", amount : 0.8867}, {sender : "seven", receiver : "c", amount : 4.2133} ]
现有代码
let i = 0; let j = 0; let thirdArray = []; while (i < firstArray.length) { let input = new BigNumber(firstArray[i].value); while (j < secondArray.length) { input = input.minus(new BigNumber(secondArray[j].value)); const formattedAmount = formatUnits(secondArray[j].value, -8); const responseObj = { sender: firstArray[i].sender, receiver: secondArray[j].recipient, amount: formattedAmount, }; if (input.isLessThan(0)) { let output = new BigNumber(secondArray[j].value); output = output.minus(input.times(-1)); thirdArray.push({ ...responseObj, amount: formatUnits(output.toNumber(), -8), }); output = input.times(-1); break; } thirdArray.push(responseObj); j += 1; if (input.isEqualTo(0)) break; } i += 1; } console.log(thirdArray)
当前错误输出
[ { sender: 'one', receiver: 'a', amount: '0.001' }, { sender: 'two', receiver: 'a', amount: '0.01' }, { sender: 'three', receiver: 'a', amount: '0.1' }, { sender: 'four', receiver: 'a', amount: '0.5' }, { sender: 'four', receiver: 'b', amount: '2.5' }, { sender: 'five', receiver: 'b', amount: '0.002' }, { sender: 'six', receiver: 'b', amount: '0.0003' }, { sender: 'seven', receiver: 'b', amount: '3.5' }, { sender: 'seven', receiver: 'c', amount: '1.5' } ]
修正后的代码
const { BigNumber } = require('bignumber.js'); // 假设formatUnits为你使用的格式化函数,示例实现如下 function formatUnits(value, decimals) { return new BigNumber(value).shiftedBy(decimals).toFixed(); } let i = 0; let j = 0; let thirdArray = []; // 维护接收方剩余需求,避免修改原数组 const remainingRecipientNeeds = secondArray.map(item => new BigNumber(item.value)); while (i < firstArray.length && j < secondArray.length) { let senderAmount = new BigNumber(firstArray[i].value); while (j < remainingRecipientNeeds.length && senderAmount.isGreaterThan(0)) { const currentNeed = remainingRecipientNeeds[j]; // 取发送方剩余金额和接收方剩余需求的较小值作为分配金额 const allocateAmount = senderAmount.lt(currentNeed) ? senderAmount : currentNeed; thirdArray.push({ sender: firstArray[i].sender, receiver: secondArray[j].recipient, amount: formatUnits(allocateAmount.toNumber(), -8) }); // 更新剩余金额和需求 senderAmount = senderAmount.minus(allocateAmount); remainingRecipientNeeds[j] = currentNeed.minus(allocateAmount); // 当前接收方需求已满足,切换到下一个 if (remainingRecipientNeeds[j].isEqualTo(0)) { j++; } } i++; } console.log(thirdArray);
修正说明
- 原代码核心问题:直接使用接收方原始需求值计算,未维护剩余需求,导致分配逻辑混乱;金额计算时的正负值处理逻辑错误,数值计算偏差。
- 关键修正点:
- 新增
remainingRecipientNeeds数组单独维护每个接收方的剩余需求,不修改原数组; - 每次循环明确计算实际分配金额(取发送方剩余金额与接收方剩余需求的较小值);
- 实时更新发送方剩余金额和接收方剩余需求,当接收方需求清零时自动切换到下一个接收方;
- 简化逻辑判断,避免复杂的正负值运算,代码更直观易维护。
- 新增
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

