Use lodash groupBy function to categorize objects in an array

淺唱寂寞╮ 提交于 2019-12-24 21:20:44

问题


i have an array of products that each product has a category object. I need to organize by category and include the category object. GroupBy function include only one parameter.

the array of products

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'}},    
]

expected result:

[
  {
    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'} ]
  },
]

回答1:


Group by the category.id, and then map the each group to an object by taking the category from the 1st item in the group, and omitting category from all products:

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>

Or the _.flow() function equivalent with lodash/fp:

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>



回答2:


Here's a solution without lodash:

You could reduce the data array. Destructure the parameter to get category and rest of the properties separately. Here rest will have id and name properties. Then create an accumulator object with each unique category's id as key. Set the value to be the final objects needed in the output. If the key already exists, update it's products array. Else, add a new key to the accumulator. Then finally use Object.values() to convert this accumulator object to an array of required 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))


来源:https://stackoverflow.com/questions/57234403/use-lodash-groupby-function-to-categorize-objects-in-an-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!