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

时间:2015-12-11 23:38:07

标签: javascript arrays coffeescript lodash

我需要通过属性对数组对象进行分组。

这是我的初始数组

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 个答案:

答案 0 :(得分: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);
}, {});

答案 1 :(得分: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);
  })
});

答案 2 :(得分: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();

不是一个班轮,但它完成了工作。基本上我会浏览每个视频对象并查看categories数组。对于每个类别,我创建相同的视频对象并添加一个虚假属性,其值为我正在查看的类别(此处我称之为_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();

不是最有效的解决方案。