【问题标题】:Group array of objects by key where key is an array按键对对象数组进行分组,其中键是数组
【发布时间】:2020-11-19 11:39:34
【问题描述】:

我们是否可以通过对象的键对对象数组进行分组,其中键也是一个数组?

[
    {
        "name": "Apple",
        "tags": ["fruits"]
    },
    {
        "name": "Orange",
        "tags": ["fruits"]
    },
    {
        "name": "Tomato",
        "tags": ["fruits", "vegetables"]
    }
]

想要的结果在group by之后的一个对象:

{
    "fruits": [
        {
            "name": "Apple",
            "tags": ["fruits"]
        },
        {
            "name": "Orange",
            "tags": ["fruits"]
        },
        {
            "name": "Tomato",
            "tags": ["fruits", "vegetables"]
        }
    ],
    "vegetables": [
        {
            "name": "Tomato",
            "tags": ["fruits", "vegetables"]
        }
    ]
}

Vanilla 或 Lodash 解决方案非常受欢迎!

编辑

谢谢大家,这是我最终使用的:

const groupBy = key => array =>
    array.reduce((obj, el) => {
        el[key].forEach(k => {
            obj[k] = obj[k] || []
            obj[k].push({ ...el })
        })
        return obj
    }, {})

const groupBySomething = groupBy(`something`)
const grouped = groupBySomething(data)

【问题讨论】:

  • 你有没有尝试过?
  • @GabrielePetrioli 我尝试使用 Lodash 的 _.groupBy 无法正常工作。

标签: javascript arrays lodash


【解决方案1】:

这使用Array.prototype.reduceArray.prototype.forEach

{
  const data = [
    {
        "name": "Apple",
        "tags": ["fruits"]
    },
    {
        "name": "Orange",
        "tags": ["fruits"]
    },
    {
        "name": "Tomato",
        "tags": ["fruits", "vegetables"]
    }
  ]
 
  const groupedData = data.reduce((carry, element) => {
    element.tags.forEach(tag => {
      carry[tag] = carry[tag] || []
      carry[tag].push({...element})
    })
    return carry; 
  }, {})
  
  console.log(groupedData)
}

【讨论】:

    【解决方案2】:

    这里:

    let arr = [
        {
            "name": "Apple",
            "tags": ["fruits"]
        },
        {
            "name": "Orange",
            "tags": ["fruits"]
        },
        {
            "name": "Tomato",
            "tags": ["fruits", "vegetables"]
        }
    ];
    
    let response = {};
    for(let i of arr){
      for(let j of i.tags){
         let tags =[...i.tags]
         if(response[j]){
            response[j].push({...i , tags: tags})
         } else{
            response[j] = [{...i, tags: tags}];
         }
      }
    }
    
    console.log(response)

    【讨论】:

      【解决方案3】:

      @yunzen 版本的稍微简洁的版本。

      输入数据:

      const data = [
          {
              "name": "Apple",
              "tags": ["fruits"]
          },
          {
              "name": "Orange",
              "tags": ["fruits"]
          },
          {
              "name": "Tomato",
              "tags": ["fruits", "vegetables"]
          }
      ];
      
      const convertData = data.reduce((target, currentElem) => {
              currentElem.tags.forEach(tag => {
                  target[tag] ? target[tag].push({...currentElem}) : target[tag] = [{...currentElem}];
              });
              return target;
      }, {});
      
      console.log(convertData);
      

      【讨论】:

        猜你喜欢
        • 2022-01-14
        • 1970-01-01
        • 2021-11-19
        • 1970-01-01
        • 2021-02-23
        • 1970-01-01
        • 2020-06-06
        • 1970-01-01
        • 2022-01-08
        相关资源
        最近更新 更多