2

Say I had an array of articles, each article may or may not have more than 1 image object, now since mysql can't group together objects, you have to do it yourself. So the result is you getting near duplicate article objects...where the only difference is the image object. By near duplicate i mean the only difference in the returned result is the image object.

I'm trying to find a way to loop through the articles array and elimate duplicate objects and create an images array which will hold each article image objects.

For example given the below array of articles:

{ 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'} },
]}

We could use the lodash reduce function, but it seems to only return the last article (articleId: 11)...It doesn't seem to find all it's images either. It will just create an images array inside each article. Note that res is the array of article objects (Like shown above)

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;
}, {});

The end result would look something like this:

{ 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'} 
   ]},
]}
2
  • You probably want to use something along the lines of groupBy. Commented Apr 29, 2016 at 3:28
  • You could exclude the articleId in the image object. Seems like redundant data since its already part of the parent article object. And if the only data coming from your images is the url than you could just use a group_concat in your mysql query and then split it later when you need to actually use the urls Commented Apr 29, 2016 at 3:30

1 Answer 1

2

You can make use of _.groupBy() to match article.articleId, then _.map() to associate each article using the first item and then set the images property by getting all image items through _.map().

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>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.11.2/lodash.js"></script>

Sign up to request clarification or add additional context in comments.

4 Comments

Ah nice. I've not used lodash at all really! It's pretty darn powerful :)
Note if you're doing this server side with node, _(data.articles) would be _.chain(data.articles) & _(items[0]) would also need _.chain(items[0]).
I'm pretty sure that it works without using _.chain() in nodejs. _.chain() is only used when you really don't want some methods to resolve without .value() such as using _.head() or _.last()
If you notice in the _.map() section I could have used chain to get the first item of the array. _.chain(items).head().omit(...).set(..).value().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.