【问题标题】:Use lodash groupBy function to categorize objects in an array使用 lodash groupBy 函数对数组中的对象进行分类
【发布时间】:2019-07-27 17:14:47
【问题描述】:

我有一个产品数组,每个产品都有一个类别对象。我需要按类别组织并包含类别对象。 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'} ]
  },
]

【问题讨论】:

  • 请在问题中加入您自己的尝试。
  • “这个问题没有显示出任何研究成果”: ...引用反对票按钮工具提示。

标签: javascript arrays reactjs lodash


【解决方案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>

【讨论】:

    【解决方案2】:

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

    您可以reduce 数据数组。 Destructure参数分别获取category和rest的属性。这里rest 将具有id 和name 属性。然后创建一个累加器对象,每个唯一类别的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))

    【讨论】:

      猜你喜欢
      • 2021-05-04
      • 1970-01-01
      • 2019-06-28
      • 1970-01-01
      • 2020-10-21
      • 1970-01-01
      • 1970-01-01
      • 2018-01-09
      • 2018-08-28
      相关资源
      最近更新 更多