2016-11-15 119 views
0

我想通过两个属性(名称和地址2)对JSON数组进行分组,然后将其减少。这是当前JSON:使用lodash应用多个分组

{ 
    "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函数内创建一个“交付”对象的数组。请帮忙! :)

+0

您的代码可能工作只是打印的console.log '[对象]'。尝试将日志更改为console.log(client.deliveris)并查看它是否更改了任何内容 – Meir

+0

@Meir - 它不起作用,它在交付内创建数组,因此invoiceNumber变为['1234','5678']等。我知道我可以通过运行额外的forEach来遍历每个对象,并构建一个将与原始数组合并的独立交付对象,但肯定必须有更好的解决方案。 – problematic

+0

如果您想知道[对象]中的内容。这样做:'var util = require('util'); console.log(util.inspect(data,{showHidden:false,depth:null}));' –

回答

1

使用一个映射,从一组挑选出你想要的属性:

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

+0

我正要回答这个问题:'deliveries:_.map(group,function(g){return _.pick g,[“invoiceNumber”,“itemDescription”,“itemQuantity”])})' –

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更多信息,下面是他们的官方文档: