簡體   English   中英

如何使用 groupby 轉換 Javascript object 並正確減少?

[英]How to transform Javascript object with groupby and reduce properly?

我需要按照 object 進行改造

  [
        {
            "name" : "sazzad",
            "type" : "credit",
            "amount" : 10
        },{
            "name" : "sazzad",
            "type" : "credit",
            "amount" : 21
        },{
            "name" : "sazzad",
            "type" : "debit",
            "amount" : 10
        },{
            "name" : "lopa",
            "type" : "credit",
            "amount" : 20
        },{
            "name" : "lopa",
            "type" : "debit",
            "amount" : 10
        }
]

關注

[
  {
    "name": "sazzad",
    "balance": 21
  },
  {
    "name": "lopa",
    "balance": 10
  }
]

我已經使用以下代碼對其進行了轉換

    function groupBy(list, keyGetter) {
        const map = new Map();
        list.forEach((item) => {
            const key = keyGetter(item);
            const collection = map.get(key);
            if (!collection) {
                map.set(key, [item]);
            } else {
                collection.push(item);
            }
        });
        return map;
    }
    const grouped = groupBy(accountTransactions, transaction => transaction.name);
    const balanceSheet = []
    for (const [key, value] of grouped) {
        balanceSheet.push(
            {
                "name": grouped.get(key)[0].name,
                "balance" : grouped.get(key).map(at => {
                    if (at.type === "credit") {
                        return at.amount
                    }else {
                        return -at.amount
                    }
                }).reduce((a,b)=>a+b,0)
            }
        );
    }

但我認為對於大型數據集,它的表現不會很好。 那么有沒有更好的方法來做到這一點?

您可以使用Array.reduce創建一個 object,其鍵等於name值,根據 transactions 數組中每個 object 的typeamount更新balance值。 然后使用Object.values將其轉換為數組:

 const transactions = [ { "name": "sazzad", "type": "credit", "amount": 10 }, { "name": "sazzad", "type": "credit", "amount": 21 }, { "name": "sazzad", "type": "debit", "amount": 10 }, { "name": "lopa", "type": "credit", "amount": 20 }, { "name": "lopa", "type": "debit", "amount": 10 } ]; const balances = Object.values(transactions.reduce((c, {name, type, amount}) => { c[name] = c[name] || { name, 'balance': 0 }; c[name].balance += type == 'credit'? amount: -amount; return c; }, {})); console.log(balances);

請注意,您可能會發現 object 更有用:

 const transactions = [ { "name": "sazzad", "type": "credit", "amount": 10 }, { "name": "sazzad", "type": "credit", "amount": 21 }, { "name": "sazzad", "type": "debit", "amount": 10 }, { "name": "lopa", "type": "credit", "amount": 20 }, { "name": "lopa", "type": "debit", "amount": 10 } ]; const balances = transactions.reduce((c, {name, type, amount}) => { c[name] = c[name] || { 'balance': 0 }; c[name].balance += type == 'credit'? amount: -amount; return c; }, {}); console.log(balances);

如果有幫助...?

 const transactions = [ { name: 'sazzad', type: 'credit', amount: 10 }, { name: 'sazzad', type: 'credit', amount: 21 }, { name: 'sazzad', type: 'debit', amount: 10 }, { name: 'lopa', type: 'credit', amount: 20 }, { name: 'lopa', type: 'debit', amount: 10 } ] const DebCred = {credit: +1, debit: -1 } const balances = Object.entries(transactions.reduce((c, {name, type, amount}) => { c[name] = c[name] || 0 c[name] += ( DebCred[type] * amount ) return c },{})).map(([k,v])=>({name:k,balance:v})) console.log(balances);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM