【问题标题】:Javascript : Summary of transactions across multiple object properties (groupby, sumby)Javascript:跨多个对象属性(groupby、sumby)的事务摘要
【发布时间】:2017-08-26 13:11:25
【问题描述】:

我有一系列跨不同货币和交易所的外汇交易:

[  
{buyCurr: "USD", sellCurr: "CAD", exchange: "Canada", buyunits: 1000, sellunits: 1200},  
{buyCurr: "EUR", sellCurr: "CAD", exchange: "Europe", buyunits: 10000, sellunits: 15000},  
{buyCurr: "GBP", sellCurr: "USD", exchange: "NYSE", buyunits: 5000, sellunits: 8000},  
{buyCurr: "USD", sellCurr: "INR", exchange: "BSE", buyunits: 3000, sellunits: 180000},  
{buyCurr: "USD", sellCurr: "JPY", exchange: "Japan", buyunits: 32000, sellunits: 1000000},  
{buyCurr: "RUB", sellCurr: "INR", exchange: "Russia", buyunits: 1000, sellunits: 1100},  
{buyCurr: "USD", sellCurr: "CNY", exchange: "China", buyunits: 3000, sellunits: 18000},  
{buyCurr: "CNY", sellCurr: "INR", exchange: "China", buyunits: 10000, sellunits: 100000},  
{buyCurr: "USD", sellCurr: "CAD", exchange: "Canada", buyunits: 1000, sellunits: 1200},  
{buyCurr: "EUR", sellCurr: "CAD", exchange: "Europe", buyunits: 10000, sellunits: 15000},  
{buyCurr: "GBP", sellCurr: "USD", exchange: "NYSE", buyunits: 5000, sellunits: 8000},  
{buyCurr: "USD", sellCurr: "INR", exchange: "BSE", buyunits: 3000, sellunits: 180000},  
{buyCurr: "USD", sellCurr: "JPY", exchange: "Japan", buyunits: 32000, sellunits: 1000000},  
{buyCurr: "RUB", sellCurr: "INR", exchange: "Russia", buyunits: 1000, sellunits: 1100},  
{buyCurr: "USD", sellCurr: "CNY", exchange: "China", buyunits: 3000, sellunits: 18000},  
{buyCurr: "CNY", sellCurr: "INR", exchange: "China", buyunits: 10000, sellunits: 100000},  
]

我想总结一下我在交易所和货币方面的头寸。所以结果看起来像:

[{
    curency : USD,
    exchange: Canada,
    units: 2000
},
{
    curency : CAD,
    exchange: Canada,
    units: -2400
},
{
    curency : USD,
    exchange: NYSE,
    units: -12000
},
......and so on
]

交易所的单位数量是(货币买入单位的总和(i))-(卖出单位的总和(i))。 SO USD 将仅对 USD 进行抵消。

我想出的一种方法是使用 forEach 遍历每个实例,过滤属性并添加/减少 buyCurr 和 sellCurr。

我也试过 lodash,但它只能让我做 groupBy 一个属性。

在 javascript 中是否有更好/更有效的方法?

【问题讨论】:

  • 一个循环怎么样?
  • 我尝试使用 forEach 但代码变得很长,所以希望有更好的方法在 javascript 中执行它,因为这似乎是一个常见问题。
  • 您的结果不清楚:CAD Canada -2400 是如何计算的? 2000 - 2400 as ((buyunits 的总和) - (sellunits 的总和)) 不等于 -2400
  • 我更新了预期的输出。一种货币只能被同一种货币抵消。所以只能从美元中减去美元。在上述情况下,我只在 CAD 上进行了两次卖出交易,以换取 1200 美元的“加拿大”,因此单位 = -1200-1200 = -2400。

标签: javascript lodash javascript-objects


【解决方案1】:

您也可以使用.reduce 来做到这一点。由于您只是添加和减去值,因此您可以边做边总结:

const input=[{buyCurr:"USD",sellCurr:"CAD",exchange:"Canada",buyunits:1e3,sellunits:1200},{buyCurr:"EUR",sellCurr:"CAD",exchange:"Europe",buyunits:1e4,sellunits:15e3},{buyCurr:"GBP",sellCurr:"USD",exchange:"NYSE",buyunits:5e3,sellunits:8e3},{buyCurr:"USD",sellCurr:"INR",exchange:"BSE",buyunits:3e3,sellunits:18e4},{buyCurr:"USD",sellCurr:"JPY",exchange:"Japan",buyunits:32e3,sellunits:1e6},{buyCurr:"RUB",sellCurr:"INR",exchange:"Russia",buyunits:1e3,sellunits:1100},{buyCurr:"USD",sellCurr:"CNY",exchange:"China",buyunits:3e3,sellunits:18e3},{buyCurr:"CNY",sellCurr:"INR",exchange:"China",buyunits:1e4,sellunits:1e5},{buyCurr:"USD",sellCurr:"CAD",exchange:"Canada",buyunits:1e3,sellunits:1200},{buyCurr:"EUR",sellCurr:"CAD",exchange:"Europe",buyunits:1e4,sellunits:15e3},{buyCurr:"GBP",sellCurr:"USD",exchange:"NYSE",buyunits:5e3,sellunits:8e3},{buyCurr:"USD",sellCurr:"INR",exchange:"BSE",buyunits:3e3,sellunits:18e4},{buyCurr:"USD",sellCurr:"JPY",exchange:"Japan",buyunits:32e3,sellunits:1e6},{buyCurr:"RUB",sellCurr:"INR",exchange:"Russia",buyunits:1e3,sellunits:1100},{buyCurr:"USD",sellCurr:"CNY",exchange:"China",buyunits:3e3,sellunits:18e3},{buyCurr:"CNY",sellCurr:"INR",exchange:"China",buyunits:1e4,sellunits:1e5}];

const output = input.reduce( ( sumObj, item ) => {
  const key = `${ item.buyCurr } ${ item.exchange }`;
  sumObj[ key ] = ( sumObj[ key ] || 0 ) + item.buyunits - item.sellunits;
  return sumObj;
}, { /* initial sumObj is going to be an empty object */ } );
console.log( output );

【讨论】:

  • 您好 Lumio,感谢您的回复。我已经更新了预期的输出以减少歧义。我是新手,所以只是学习:)。
【解决方案2】:

我想不出一种方法可以一次性完成所有操作,但是通过函数中的一些逻辑,您可以运行 3 次:

  • 购买交易
  • 卖出交易
  • 合并交易

之后,您将获得汇总的答案。不如一次性好,但提供的功能足够灵活,可以处理所有 3 种情况: (您需要向下滚动才能查看完整代码)

const transactions = [  
{buyCurr: "USD", sellCurr: "CAD", exchange: "Canada", buyunits: 1000, sellunits: 1200},  
{buyCurr: "EUR", sellCurr: "CAD", exchange: "Europe", buyunits: 10000, sellunits: 15000},  
{buyCurr: "GBP", sellCurr: "USD", exchange: "NYSE", buyunits: 5000, sellunits: 8000},  
{buyCurr: "USD", sellCurr: "INR", exchange: "BSE", buyunits: 3000, sellunits: 180000},  
{buyCurr: "USD", sellCurr: "JPY", exchange: "Japan", buyunits: 32000, sellunits: 1000000},  
{buyCurr: "RUB", sellCurr: "INR", exchange: "Russia", buyunits: 1000, sellunits: 1100},  
{buyCurr: "USD", sellCurr: "CNY", exchange: "China", buyunits: 3000, sellunits: 18000},  
{buyCurr: "CNY", sellCurr: "INR", exchange: "China", buyunits: 10000, sellunits: 100000},  
{buyCurr: "USD", sellCurr: "CAD", exchange: "Canada", buyunits: 1000, sellunits: 1200},  
{buyCurr: "EUR", sellCurr: "CAD", exchange: "Europe", buyunits: 10000, sellunits: 15000},  
{buyCurr: "GBP", sellCurr: "USD", exchange: "NYSE", buyunits: 5000, sellunits: 8000},  
{buyCurr: "USD", sellCurr: "INR", exchange: "BSE", buyunits: 3000, sellunits: 180000},  
{buyCurr: "USD", sellCurr: "JPY", exchange: "Japan", buyunits: 32000, sellunits: 1000000},  
{buyCurr: "RUB", sellCurr: "INR", exchange: "Russia", buyunits: 1000, sellunits: 1100},  
{buyCurr: "USD", sellCurr: "CNY", exchange: "China", buyunits: 3000, sellunits: 18000},  
{buyCurr: "CNY", sellCurr: "INR", exchange: "China", buyunits: 10000, sellunits: 100000},  
];

function positionSummary(transactions, summaryType) {
    const newList = _(transactions)
        .groupBy(summaryType === 'currency' ? summaryType : `${summaryType}Curr`)
        .map(action => {
            return _.groupBy(action, 'exchange');
        })
        .map(currency => {
            return _.map(currency, exchangeArray => {
                const currency = _.first(exchangeArray)[summaryType === 'currency' ? summaryType : `${summaryType}Curr`];
                const exchange = _.first(exchangeArray)['exchange'];
                let units = _(exchangeArray)
                    .sumBy(summaryType === 'currency' ? 'units' : `${summaryType}units`)
                    .valueOf();
                units = _.multiply(units, summaryType === 'sell' ? -1 : 1);

                return {
                    currency,
                    exchange,
                    units
                };
            });
        })
        .flatten()
        .valueOf();


    console.log(summaryType, newList);
    return newList;
}

const buyUnitSummary = positionSummary(transactions, 'buy');
const sellUnitSummary = positionSummary(transactions, 'sell');
const allUnitSummary = _.concat(buyUnitSummary, sellUnitSummary);
const finalPositionSummary = positionSummary(allUnitSummary, 'currency');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

【讨论】:

    猜你喜欢
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    • 2017-09-12
    • 1970-01-01
    • 1970-01-01
    • 2014-06-14
    • 1970-01-01
    相关资源
    最近更新 更多