我抽象一下这个问题:invoices 是销售行为,transaction 是对余额的操作行为,一通存取反复拉扯之后形成的余额,尝试去扣款,如果余额足够就允许交易,如果余额不足就拒绝交易。
const invoices = [
{ id: 'INV001', type: 'Buy', amount: 100 }
];
const balanceTransactions = [
{ id: 'JNL001', type: 'transaction', amount: 100 },
{ id: 'JNL002', type: 'transaction', amount: -100 },
{ id: 'JNL003', type: 'transaction', amount: 100 },
{ id: 'JNL004', type: 'transaction', amount: -100 },
{ id: 'JNL005', type: 'transaction', amount: 130}
];
以上情况中,应该是 JNL001 到 JNL005 都被使用了,截至 JNL005 余额还剩 30 块,invoice 是 100 块。换句话说,就是尽可能多地查找余额的操作行为,确定哪些行为可以归结到这张 invoice 下。
请问这叫什么算法,以下是 GPT 的结果肯定是不对的
function performVerification() {
const verifications = []; // 存储核销结果
let remainingAmount = 0; // 剩余待核销金额
// 按日期排序单据数组
const sortedInvoices = invoices.sort((a, b) => a.date - b.date);
const sortedJournals = journals.sort((a, b) => a.date - b.date);
// 遍历单据数组进行核销
for (const invoice of sortedInvoices) {
let verifiedAmount = 0; // 当前单据已核销金额
const verifiedJournals = []; // 当前单据核销的 journal 数组
// 倒序遍历 journals 进行核销
for (let i = sortedJournals.length - 1; i >= 0; i--) {
const journal = sortedJournals[i];
if (journal.amount < 0 && Math.abs(journal.amount) <= remainingAmount) {
// 负数调整余额
verifiedAmount += Math.abs(journal.amount);
verifiedJournals.push({ id: journal.id, amount: Math.abs(journal.amount) });
remainingAmount -= Math.abs(journal.amount);
sortedJournals.splice(i, 1); // 从数组中移除已核销的 journal
}
// 如果当前单据已核销金额达到单据金额,则退出循环
if (verifiedAmount >= invoice.amount) {
break;
}
}
// 添加核销结果到数组
verifications.push({ invoice, verifiedAmount, verifiedJournals });
// 如果已核销所有 journals ,则跳出循环
if (sortedJournals.length === 0) {
break;
}
}
return verifications;
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.