繁体   English   中英

javascript减少了数组中对象的多个键

[英]javascript reduce over multiple keys of objects in an array

我有以下类型的Object地图(下面的示例数据)

{[date:string]:Array<{[type:string]:{amount:number, price:number}}>}

我需要将数组减少到单个金额总和和平均价格的对象

我已经阅读了几篇关于如何通过像这样的对象减少数据的帖子

如何映射和减少对象数组?

Javascript减少了对象数组

在我的情况下,“类型”是[“PV”,“BHKW”,“FALLBACK”]的ENUM,但它可以扩展。 除了为in循环编写声明之外,我无法弄清楚如何使用array.reduce来更优雅地完成它。

有什么建议么?

{
    "2018-08-01T11:00:00+02:00": [
        {
            "BHKW": {
                "amount": 131,
                "price": 85
            },
            "FALLBACK": {
                "amount": 84,
                "price": 1
            }
        },
        {
            "BHKW": {
                "amount": 307,
                "price": 58
            },
            "PV": {
                "amount": 4,
                "price": 60
            }
        }
    ],
    "2018-08-01T12:00:00+02:00": [
        {
            "BHKW": {
                "amount": 288,
                "price": 59
            },
            "PV": {
                "amount": 742,
                "price": 73
            }
        },
        {
            "BHKW": {
                "amount": 250,
                "price": 49
            },
            "PV": {
                "amount": 507,
                "price": 98
            }
        },
        {
            "PV": {
                "amount": 368,
                "price": 22
            },
            "BHKW": {
                "amount": 357,
                "price": 73
            }
        },
        {
            "FALLBACK": {
                "amount": 135,
                "price": 62
            },
            "BHKW": {
                "amount": 129,
                "price": 93
            }
        }
    ],

您可以使用lodash#mapValues转换对象data对象的每个值。 要将所有对象与相同的键值组合在一起,您可以将lodash#mergeWith与回调测试lodash#mergeWith使用,如果要对要转换的键进行求值。

const result = _.mapValues(data, collection => 
  _.mergeWith({}, ...collection, (a = 0, b = 0, key) =>
    ['amount', 'price'].includes(key)
      ? a + b
      : void 0 // is equivalent to undefined to retain current value
  ));

 const data = { "2018-08-01T11:00:00+02:00": [ { "BHKW": { "amount": 131, "price": 85 }, "FALLBACK": { "amount": 84, "price": 1 } }, { "BHKW": { "amount": 307, "price": 58 }, "PV": { "amount": 4, "price": 60 } } ], "2018-08-01T12:00:00+02:00": [ { "BHKW": { "amount": 288, "price": 59 }, "PV": { "amount": 742, "price": 73 } }, { "BHKW": { "amount": 250, "price": 49 }, "PV": { "amount": 507, "price": 98 } }, { "PV": { "amount": 368, "price": 22 }, "BHKW": { "amount": 357, "price": 73 } }, { "FALLBACK": { "amount": 135, "price": 62 }, "BHKW": { "amount": 129, "price": 93 } } ] }; const result = _.mapValues(data, collection => _.mergeWith({}, ...collection, (a = 0, b = 0, key) => ['amount', 'price'].includes(key) ? a + b : void 0 // is equivalent to undefined to retain current value )); console.log(result); 
 .as-console-wrapper{min-height:100%;top:0} 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script> 

解决了!

var x = _.reduce(
    list,
    (acc, item) => {
        for (const key in item) {
            if (!acc[key]) {
                acc[key] = { price: 0, amount: 0 };
            }

            if (item[key] && item[key].price) {
                acc[key].price += item[key].price;
            }

            if (item[key] && item[key].amount) {
                acc[key].amount += item[key].amount;
            }
        }
        return acc;
    },
    {}
);

另一种方式(尽管不像已经发布的_.merge方法那样优雅)是_.mapValues/_.reduce/_.assignWith or _.extendWith

 var data = { "2018-08-01T11:00:00+02:00": [{ "BHKW": { "amount": 131, "price": 85 }, "FALLBACK": { "amount": 84, "price": 1 } }, { "BHKW": { "amount": 307, "price": 58 }, "PV": { "amount": 4, "price": 60 } } ], "2018-08-01T12:00:00+02:00": [{ "BHKW": { "amount": 288, "price": 59 }, "PV": { "amount": 742, "price": 73 } }, { "BHKW": { "amount": 250, "price": 49 }, "PV": { "amount": 507, "price": 98 } }, { "PV": { "amount": 368, "price": 22 }, "BHKW": { "amount": 357, "price": 73 } }, { "FALLBACK": { "amount": 135, "price": 62 }, "BHKW": { "amount": 129, "price": 93 } } ] } var result = _.mapValues(data, (x) => _.reduce(x, (r, c) => _.assignWith(r, c, (o, s) => o && s ? ({ amount: o.amount + s.amount, price: o.price + s.price }) : {...o, ...s}) ) ) console.log(result) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM