LoDash - 按照数组属性分组而不将值作为一个键

3

我需要按一个属性对一个对象数组进行分组,这个属性本身也是一个数组。

这是我的初始数组:

var videos = [
   {
    name: 'Video 1',
    productInfo:{
        categories: ['cat1', 'cat2']}
   },
   {
    name: 'Video 2',
    productInfo:{
        categories: ['cat2']}
   },
   {
    name: 'Video 3',
    productInfo:{
        categories: ['cat1', 'cat3']}   
   }
];

当我使用这个时

_.groupBy videos, 'productInfo.categories'

我的回复是

 {
  'cat1, cat2': Array[1],
  'cat1, cat3': Array[1],
  'cat2': Array[1]
 }

我已经尝试了另一个人提供的答案,他也遇到了同样的问题,但结果不同。
尝试他的解决方案。
_.groupBy _.flatten _.pluck videos, 'productInfo.categories'

我明白了

{
  'cat1': ['cat1', 'cat1'], 
  'cat2': ['cat2', 'cat2'],
  'cat3': ['cat3'] 
}

我需要你作为回应

{
'cat1': [videoObject, videoObject], 
'cat2': [videoObject, videoObject],
'cat3': [videoObject] 
}

感谢您的帮助!
3个回答

2
var res = _.reduce(videos, function(result, video){
    return _.reduce(video.productInfo.categories, function(acc, category){
        (acc[category] || (acc[category] = [])).push(video);
        return acc;
    }, result);
}, {});

0

我认为这大致是您要寻找的内容。可能还有更优雅的解决方案。

var videos = [
  {
    name: 'Video 1',
    productInfo: {
      categories: ['cat1', 'cat2']
    }
  },
  {
    name: 'Video 2',
    productInfo: {
      categories: ['cat2']
    }
  },
  {
   name: 'Video 3',
    productInfo: {
      categories: ['cat1', 'cat3']
    }
  }
];

var collection = {};
_.each(videos, function(video) {
  _.each(video.productInfo.categories, function (category) {
    collection[category] = collection[category] ? collection[category] : [];
    collection[category].push(video);
  })
});

为了获得您的代码所期望的结果,transform 应该像这样:var result = _.transform(videos, function (collection, video) { ... }, { }); - Shanoor

0

试试这个:

var result = _.chain(videos)
  .map(function(video) {
    return _.map(_.get(video, 'productInfo.categories', []), function ( cat ) {
      return _.extend({ '_category': cat }, video);
    });
  })
  .flatten()
  .groupBy('_category')
  .value();

虽然不是一行代码,但它可以完成工作。基本上,我会遍历每个视频对象并查看类别数组。对于每个类别,我创建相同的视频对象,并添加一个假属性,其值为我正在查看的类别(这里我称之为_category)。然后我在假属性上调用_.groupBy

如果您想要在结果中去除假属性,可以在链中添加另一个函数来省略该属性:

var result = _.chain(videos)
  .map(function(video) {
    return _.map(_.get(video, 'productInfo.categories', []), function ( cat ) {
      return _.extend({ '_category': cat }, video);
    });
  })
  .flatten()
  .groupBy('_category')
  .transform(function(result, videos, category) {
    result[ category ] = _.map(videos, function(video) {
      return _.omit(video, '_category')
    });
  })
  .value();

不是最有效率的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接