[英]Comparing values from two arrays and creating objects accordingly
第一次寫問題,所以我會盡量弄清楚問題是什么。
我有 2 個 arrays 填充了不同的值,我正在嘗試 map 來自第一個數組的值是值的輸入,到第二個是輸出。
如果第一個數組中的第一個 object 小於第二個數組中的數量,則就像第一個 object 將其所有值發送到第二個 object 一樣,每個 object 依此類推,直到滿足第二個 object 的值。
通過這種方式,我想從一個 object 到另一個 map 值,例如,如果第一個 object 中的值大於第二個 object,他將發送部分第一個對象值來滿足整個第二個 object 和然后部分還有下一個....這是 arrays 以及它應該如何結束的示例。
我還使用 BigNumber.js 和 formatUnit function 來整理數字。
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"}
]
我想做的是:
我想很好地 map 以便最終數組看起來如下所示:
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));
// Format units for amount
const formattedAmount = formatUnits(secondArray[j].value, -8);
// Initialize responseObject
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' }
]
與我想要得到的相比:
[
{ 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 }
]
任何幫助將非常感激!
我將問題解釋為...鑒於這些類型:
interface Sender {
sender: string;
value: number;
}
interface Recipient {
recipient: string;
value: number;
}
interface Transaction extends Sender, Recipient { }
執行以下 function:
declare function getTransactionArray(
senderArray: Sender[],
recipientArray: Recipient[]
): Transaction[];
senderArray
中的發件人按順序向 recipientArray 中的recipientArray
發送值,但是您保留當前發件人直到她發送所有此處的值,並且您保留當前收件人直到他收到她的所有值。
這是一種方法:
function getTransactionArray(senderArray: Sender[], recipientArray: Recipient[]
) {
const epsilon = 1e-10; // anything less than this is considered zero
// copy arrays
senderArray = senderArray.map(s => ({ ...s }));
recipientArray = recipientArray.map(s => ({ ...s }));
const transactionArray: Transaction[] = [];
while (senderArray.length && recipientArray.length) {
const sender = senderArray[0];
const recipient = recipientArray[0];
const value = Math.min(sender.value, recipient.value);
sender.value -= value; // perform transaction
recipient.value -= value; // perform transaction
transactionArray.push({ // record transaction
sender: sender.sender,
recipient: recipient.recipient,
value
});
if (!(sender.value > epsilon)) senderArray.shift();
if (!(recipient.value > epsilon)) recipientArray.shift();
}
if (senderArray.length) console.log("WARNING! No receipients for", senderArray);
if (recipientArray.length) console.log("WARNING! No senders for ", recipientArray);
return transactionArray;
}
這是一個命令式算法,我們復制senderArray
和recipientArray
數據並對副本進行變異(與沒有 state 更改的純函數算法相反)。
這個想法是我們獲取第一個發送者和第一個接收者(如果沒有第一個發送者,或者如果沒有第一個接收者,那么我們就完成了)並確定要發送的值。 這是發送者想要發送的值和接收者想要接收的值中的最小值。 然后我們通過從發送者和接收者中減去這個值來執行交易。 並且我們將交易記錄在 output 數組中。 最后,如果發送者發送了她所有的值,則發送者從數組中刪除,如果接收者收到了他的所有值,則從數組中刪除。
(請注意,我將剩余的值數量與epsilon
進行了比較;我使用 JavaScript 的標准浮點算法進行計算,因此有時由於精度問題,您可能會得到一個發件人或收件人剩余微小的正值......之后all, 0.1 + 0.2 - 0.3 !== 0
。所以我選擇了一些epsilon
,我希望它比我們關心的任何實際數量都小。如果你使用不同的數字數據結構,那么你可能會改變這種比較的完成方式。)
最后,如果發件人留下一些未發送的值或收件人留下一些未收到的值,我們可能會在可能記錄警告之后返回交易數組......如果發件人值的總和不匹配,就會發生這種情況收件人值的總和。
讓我們測試一下:
const senderArray: Sender[] = [
{ 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" },
{ value: 0.1, sender: "eight" }
];
const recipientArray: Recipient[] = [
{ value: 0.5, recipient: "a" },
{ value: 3.5, recipient: "b" },
{ value: 4.2133, recipient: "c" }
];
我在其中添加了另一個發件人以使總和相等:
const transactionArray = getTransactionArray(senderArray, recipientArray);
console.log("[\n" + transactionArray.map(v =>
JSON.stringify(({ ...v, value: v.value.toFixed(4) }))
).join(",\n") + "\n]");
/* [
{"sender":"one","recipient":"a","value":"0.0010"},
{"sender":"two","recipient":"a","value":"0.0100"},
{"sender":"three","recipient":"a","value":"0.1000"},
{"sender":"four","recipient":"a","value":"0.3890"},
{"sender":"four","recipient":"b","value":"2.6110"},
{"sender":"five","recipient":"b","value":"0.0020"},
{"sender":"six","recipient":"b","value":"0.0003"},
{"sender":"seven","recipient":"b","value":"0.8867"},
{"sender":"seven","recipient":"c","value":"4.1133"},
{"sender":"eight","recipient":"c","value":"0.1000"}
]*/
看起來不錯!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.