使用lodash应用多个分组

时间:2016-11-15 14:58:41

标签: arrays json node.js dictionary lodash

我想通过两个属性(name和address2)对JSON数组进行分组,然后将其减少。这是当前的JSON:

{
    "clientId": "FOO",
    "name": "John Doe",
    "address1": "London",
    "address2": "1 High Street",
    "invoiceNumber": "1234",
    "itemDescription": "Item 1",
    "itemQuantity": 1
},
{
    "clientId": "BAR",
    "name": "John Doe",
    "address1": "London",
    "address2": "1 Oxford Street",
    "invoiceNumber": "0987",
    "itemDescription": "Item 2",
    "itemQuantity": 1
},
{
    "clientId": "FOO",
    "name": "John Doe",
    "address1": "London",
    "address2": "1 High Street",
    "invoiceNumber": "5678",
    "itemDescription": "Item 3",
    "itemQuantity": 1
}

这就是我想要实现的目标:

[
    {
        "clientId": "FOO",
        "name": "John Doe",
        "address1": "London",
        "address2": "1 High Street",
        "deliveries": [
            {
                "invoiceNumber": "1234",
                "itemQuantity": 1,
                "itemDescription": "Item 1"
            },
            {
                "invoiceNumber": "5678",
                "itemDescription": "Item3",
                "itemQuantity": 1
            }
        ]
    },
    {
        "clientId": "BAR",
        "name": "JohnDoe",
        "address1": "London",
        "address2": "12 Oxford Street",
        "deliveries": [
            {
                "invoiceNumber": "0987",
                "itemDescription": "Item2",
                "itemQuantity": 1
            }
        ]
    }
]

这是我到目前为止的代码,它没有产生我希望的代码:

        var groups = _.groupBy(rows, function(value) {
            return value.name + '#' + value.address2;
        });

        var data = _.map(groups, function(group) {
            return {
                clientId: group[0].clientId,
                name: group[0].name,
                address1: group[0].address1,
                address2: group[0].address2,
                deliveries: [{
                    invoiceNumber: _.map(group,'invoiceNumber'),
                    itemDescription: _.map(group,'itemDescription'),
                    itemQuantity: _.map(group,'itemQuantity'),
                }]
            }
        });

它产生以下输出:

[ { clientId: 'FOO',
    name: 'John Doe',
    address1: 'London',
    address2: '1 High Street',
    deliveries: [ [Object] ] } ]

我不确定如何创建一系列"交付" lodash _.map函数中的对象。请帮忙! :)

2 个答案:

答案 0 :(得分:1)

使用一个地图从组中挑选出您想要的属性:

... deliveries: _.map(group, item => _.pick(item, ['invoiceNumber', 'itemDescription', 'itemQuantity' ])) ...

答案 1 :(得分:0)

你离我不远!

根据Gruff的建议,通过使用ES6语法并将_.pick()合并到代码中,可以更简洁一点。

如果你真的喜欢单行,那也是可能的!尽管你可能会损害一些可读性,但Lodash可以很容易地链接/嵌套函数:

// Data:
const rows = [{
  "clientId": "FOO",
  "name": "John Doe",
  "address1": "London",
  "address2": "1 High Street",
  "invoiceNumber": "1234",
  "itemDescription": "Item 1",
  "itemQuantity": 1
},
{
  "clientId": "BAR",
  "name": "John Doe",
  "address1": "London",
  "address2": "1 Oxford Street",
  "invoiceNumber": "0987",
  "itemDescription": "Item 2",
  "itemQuantity": 1
},
{
  "clientId": "FOO",
  "name": "John Doe",
  "address1": "London",
  "address2": "1 High Street",
  "invoiceNumber": "5678",
  "itemDescription": "Item 3",
  "itemQuantity": 1
}];

// Result:
const groups = _.groupBy(rows, item => item.clientId);
const result = _.map(groups, group => {
  const {clientId, name, address1, address2} = group[0];
  const deliveries = _.map(group, item => _.pick(item, ['invoiceNumber', 'itemDescription', 'itemQuantity']));
  return {clientId, name, address1, address2, deliveries};
});
console.log('multi-liner result: ', result);

// One-line version:
const oneLiner = _.map(_.groupBy(rows, item => item.clientId), group => _.merge(_.pick(group[0], ['clientId', 'name', 'address1', 'address2']), {deliveries: _.map(group, item => _.pick(item, ['invoiceNumber', 'itemDescription', 'itemQuantity']))}));
console.log('one-liner result: ', oneLiner);
<script src="https://cdn.jsdelivr.net/lodash/4.17.1/lodash.min.js"></script>

希望有所帮助!如果您想了解有关所使用的Lodash功能的更多信息,请参阅以下官方文档: