JS / lodash - 转换对象的集合

时间:2017-02-01 19:17:05

标签: javascript arrays lodash javascript-objects

我正在寻找一个Lodash / JS解决方案来从下面的结构转换集合(对象数组):

let collection = [
    { category: "cat_1", banner: "banner_A", id: 1 },
    { category: "cat_1", banner: "banner_B", id: 2 },
    { category: "cat_2", banner: "banner_C", id: 3 },
    { category: "cat_2", banner: "banner_D", id: 4 },
    { category: "cat_2", banner: "banner_A", id: 5 },
    { category: "cat_3", banner: "banner_B", id: 6 }
];

进入新结构:

let newCollection = [
    { 
      category: "cat_1", 
      banners: [
        { banner: "banner_A", id: 1 },
        { banner: "banner_B", id: 2 },
      ]
    },
    { 
      category: "cat_2", 
      banners: [
        { banner: "banner_C", id: 3 },
        { banner: "banner_D", id: 4 },
        { banner: "banner_A", id: 5 },
      ]
    },
    { 
      category: "cat_3", 
      banners: [
        { banner: "banner_B", id: 6 }
      ]
    }
]

有什么想法吗? :) CHeers!

2 个答案:

答案 0 :(得分:2)

这是一个解决方案,首先按类别groups数据,然后在每个组中maps以获取所需表单中的数据。 omit用于从每个项目中删除类别属性。

let result = _(collection)
    .groupBy('category')
    .map( (group, category) => ({
        category: category,
        banners: _.map(group, banner => _.omit(banner, 'category'))
    }))
    .value();

答案 1 :(得分:1)

这是一个使用普通JS的非常简单的方法。

它基本上遍历集合并尝试在newCollection数组中找到具有匹配category属性的条目。如果找到一个条目,它会将一个新对象推送到那些条目中。 banners数组,否则它将整个新的条目对象推送到newCollection数组。



var collection = [
    { category: "cat_1", banner: "banner_A", id: 1 },
    { category: "cat_1", banner: "banner_B", id: 2 },
    { category: "cat_2", banner: "banner_C", id: 3 },
    { category: "cat_2", banner: "banner_D", id: 4 },
    { category: "cat_2", banner: "banner_A", id: 5 },
    { category: "cat_3", banner: "banner_B", id: 6 }
];

var newCollection = [];
collection.forEach(item => {
  var entry = newCollection.find(x => x.category === item.category);
  var content = { banner: item.banner, id: item.id };

  if (!entry) {
    newCollection.push({
      category: item.category,
      banners: [content]
    });
  } else {
    entry.banners.push(content);
  }
});

console.log(newCollection);