使用lodash groupBy函数对数组中的对象进行分类

时间:2019-07-27 17:14:47

标签: javascript arrays reactjs lodash

我有一系列产品,每个产品都有一个类别对象。我需要按类别组织并包括类别对象。 GroupBy函数仅包含一个参数。

产品系列

const data = [   
  {id: 1, 'name': 'produto1', category: {id: 1, name: 'shirts', description: 'super roupa'}},
  {id: 2, 'name': 'produto2', category: {id: 1, name: 'shirts', description: 'super roupa'}},
  {id: 3, 'name': 'produto3', category: {id: 2, name: 'jackets', description: 'super jackets'}},
  {id: 4, 'name': 'produto4', category: {id: 2, name: 'jackets', description: 'super jackets'}},    
]

预期结果:

[
  {
    category: {id: 1, name: 'clothes', description: 'super roupa'}, 
    products:[{id:1, name: 'produt1'}, {id: 2, name: 'produto1'} ]
  },
  {
    category: {id: 2, name: 'jackets', description: 'super jackets'}, 
    products:[{id:3, name: 'produt3'}, {id: 4, name: 'produto4'} ]
  },
]

2 个答案:

答案 0 :(得分:1)

category.id分组,然后通过从组中第一项中选取category,并从所有产品中省略category,将每个组映射到一个对象:

const data = [{"id":1,"name":"produto1","category":{"id":1,"name":"shirts","description":"super roupa"}},{"id":2,"name":"produto2","category":{"id":1,"name":"shirts","description":"super roupa"}},{"id":3,"name":"produto3","category":{"id":2,"name":"jackets","description":"super jackets"}},{"id":4,"name":"produto4","category":{"id":2,"name":"jackets","description":"super jackets"}}]

const result = _(data)
  .groupBy('category.id')
  .map(group => ({
    category: _.head(group).category,
    products: _.map(group, o => _.omit(o, 'category'))
  }))
  .value()

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

或与lodash / fp等效的_.flow()函数:

const { flow, groupBy, map, head, omit } = _

const fn = flow(
  groupBy('category.id'),
  map(group => ({
    category: head(group).category,
    products: map(omit('category'), group)
  }))
)

const data = [{"id":1,"name":"produto1","category":{"id":1,"name":"shirts","description":"super roupa"}},{"id":2,"name":"produto2","category":{"id":1,"name":"shirts","description":"super roupa"}},{"id":3,"name":"produto3","category":{"id":2,"name":"jackets","description":"super jackets"}},{"id":4,"name":"produto4","category":{"id":2,"name":"jackets","description":"super jackets"}}]

const result = fn(data)

console.log(result)
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>

答案 1 :(得分:1)

这是一个没有lodash的解决方案:

您可以reduce数据数组。 Destructure个参数,分别获取属性categoryrest。这里的rest将具有idname属性。然后,使用每个唯一类别的id作为键,创建一个累加器对象。将值设置为输出中所需的最终对象。如果密钥已经存在,请更新它的products数组。否则,向累加器添加一个新密钥。然后最后使用Object.values()将此累加器对象转换为所需值的数组

const data = [{"id":1,"name":"produto1","category":{"id":1,"name":"shirts","description":"super roupa"}},{"id":2,"name":"produto2","category":{"id":1,"name":"shirts","description":"super roupa"}},{"id":3,"name":"produto3","category":{"id":2,"name":"jackets","description":"super jackets"}},{"id":4,"name":"produto4","category":{"id":2,"name":"jackets","description":"super jackets"}}]

const merged = data.reduce((acc, { category, ...rest }) => {
  acc[category.id] = acc[category.id] || { category, products: [] };
  acc[category.id].products.push(rest);
  return acc;
}, {})

console.log(Object.values(merged))