【问题标题】:How can I merge an array of objects?如何合并对象数组?
【发布时间】:2016-04-29 12:28:17
【问题描述】:

假设我有一个文章数组,每篇文章可能有也可能没有超过1个图像对象,现在由于mysql不能将对象组合在一起,你必须自己做。所以结果是您得到接近 重复的文章对象...唯一的区别是图像对象。 接近重复我的意思是返回结果的唯一区别是图像对象。

我正在尝试找到一种方法来循环遍历 articles 数组并消除重复对象并创建一个 images 数组来保存每个 article 图像对象。

例如给定以下文章数组:

{ articles: [
   {article: {articleId: 10, articleText: 'blah'}, image: {articleId: 10,  imageUrl: 'http://differentUrlTooBelow'} },
   {article: {articleId: 10, articleText: 'blah'}, image: {articleId: 10, imageUrl: 'http://AnotherUrlDifferentToAbove'} },
   {article: {articleId: 11, articleText: 'ajsdnfa'}, image: {articleId: 11, imageUrl: 'http://DifferentUrlTooBelow'} },
   {article: {articleId: 11, articleText: 'asfdjnasjdf'}, image: {articleId: 11, imageUrl: 'http://AnotherUrlDifferentToAbove'} },
]}

我们可以使用 lodash reduce 函数,但它似乎只返回最后一个 article (articleId: 11)...它似乎也找不到它的所有图像。它只会在每篇文章中创建一个图像数组。请注意,resarticle 对象的数组(如上所示)

var z = _.reduce(res, function(result, value, key) {
if (key == 0) return;
if(value.article['articleId'] == res[key-1].article['articleId']) {
  result = value;
  result.images = [];
  result.images.push(result.image);
}

return result;
}, {});

最终结果如下所示:

{ articles: [
   {article: {articleId: 10, articleText: 'blah'}, 
    images: [
       {articleId: 10,  imageUrl: 'http://differentUrlTooBelow'},
       {articleId: 10, imageUrl: 'http://AnotherUrlDifferentToAbove'} 
   ]},
   {article: {articleId: 11, articleText: 'blah'}, 
    images: [
       {articleId: 11,  imageUrl: 'http://differentUrlTooBelow'},
       {articleId: 11, imageUrl: 'http://AnotherUrlDifferentToAbove'} 
   ]},
]}

【问题讨论】:

  • 您可能想使用类似于groupBy 的东西。
  • 您可以排除图像对象中的articleId。似乎是冗余数据,因为它已经是父 article 对象的一部分。如果来自图像的唯一数据是 url,那么您可以在 mysql 查询中使用 group_concat,然后在您需要实际使用 url 时将其拆分

标签: javascript arrays lodash


【解决方案1】:

您可以使用_.groupBy() 匹配article.articleId,然后_.map() 使用第一项关联每篇文章,然后通过_.map() 获取所有image 项目来设置images 属性。

var data = { 
  articles: [
   {
     article: {articleId: 10, articleText: 'blah'}, 
     image: { articleId: 10, imageUrl: 'http://differentUrlTooBelow' } 
   },
   {
     article: {articleId: 10, articleText: 'blah'}, 
     image: { articleId: 10, imageUrl: 'http://AnotherUrlDifferentToAbove' } 
   },
   {
     article: {articleId: 11, articleText: 'ajsdnfa'}, 
     image: { articleId: 11, imageUrl: 'http://DifferentUrlTooBelow' }
   },
   {
     article: {articleId: 11, articleText: 'asfdjnasjdf'}, 
     image: { articleId: 11, imageUrl: 'http://AnotherUrlDifferentToAbove' } 
   }
  ]
};

var result = {
  articles: _(data.articles)
    .groupBy('article.articleId')
    .map(function(items) {
      return _(items[0])
        .omit('image')
        .set('images', _.map(items, 'image'))
        .value();
    })
    .value()
};

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.11.2/lodash.js"&gt;&lt;/script&gt;

【讨论】:

  • 不错。我真的根本没有使用过lodash!它非常强大:)
  • 请注意,如果您使用节点执行此服务器端,_(data.articles) 将是 _.chain(data.articles)_(items[0]) 还需要 _.chain(items[0])
  • 我很确定它可以在 nodejs 中不使用 _.chain() 的情况下工作。 _.chain() 仅在您确实不希望某些方法在没有 .value() 的情况下解决时使用,例如使用 _.head()_.last()
  • 如果您在_.map() 部分注意到我可以使用链来获取数组的第一项。 _.chain(items).head().omit(...).set(..).value().
猜你喜欢
  • 1970-01-01
  • 2019-03-16
  • 2020-07-11
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多