最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Group array of objects by key where key is an array - Stack Overflow

programmeradmin3浏览0评论

Can we achieve a group by on an array of objects by object's key where key is also an array?

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

Wanted results in an object after the group by:

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

Vanilla or Lodash solution is very wele!

Edit

Thanks everyone, here is what I ended up using:

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)

Can we achieve a group by on an array of objects by object's key where key is also an array?

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

Wanted results in an object after the group by:

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

Vanilla or Lodash solution is very wele!

Edit

Thanks everyone, here is what I ended up using:

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)
Share Improve this question edited Nov 19, 2020 at 12:04 wassim asked Nov 19, 2020 at 11:39 wassimwassim 391 silver badge8 bronze badges 2
  • Have you tried anything ? – Gabriele Petrioli Commented Nov 19, 2020 at 11:43
  • @GabrielePetrioli I tried with Lodash's _.groupBy couldn't get it working. – wassim Commented Nov 19, 2020 at 11:45
Add a ment  | 

3 Answers 3

Reset to default 3

This uses Array.prototype.reduce and Array.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)
}

Here:

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)

A slightly more terse version of @yunzen version.

input data:

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);
发布评论

评论列表(0)

  1. 暂无评论