Lorenzo Martín
Lorenzo Martín

Reputation: 111

Lodash group By

What I need is to group by project, that for each project I am grouped by the stories that are in those projects, and that for each story I show the tasks. When executing the example, we will see that the history 41 that corresponds to the "barney" project is not shown. It groups the stories but does not show the history corresponding to a barney that is not grouped. This is an example of how it should look

 [
  {
    "proyecto": "barney",
    "historia": 42,
    "tarea": [
      "dog",
      "lion",
      "cat"
    ],
    "historia": 41,
    "tarea": [
      "cat"
    ]
  },
  {
    "proyecto": "fred",
    "historia": 35,
    "tarea": [
      "dog",
      "goldfish"
    ]
  }
]

group();

function group()
{

var characters = [
  { 'proyecto': 'barney', 'historia': 42,  'tarea': 'dog' },
  { 'proyecto': 'barney', 'historia': 42,  'tarea': 'lion' },
  { 'proyecto': 'fred',   'historia': 35,  'tarea': 'dog' },
  { 'proyecto': 'barney', 'historia': 41,  'tarea': 'cat' },
  { 'proyecto': 'fred',   'historia': 35,  'tarea': 'goldfish' }
];

var result=_.chain(characters).groupBy("proyecto").map(function(v, i) {
  return {
    proyecto: i,
    historia: _.get(_.find(v, 'historia'), 'historia'),
    tarea: _.map(v, 'tarea')
  }
}).value();
document.body.innerHTML = '<pre>' + JSON.stringify(result, null, '  ') + '</pre>';
	
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

Upvotes: 1

Views: 557

Answers (2)

Akrion
Akrion

Reputation: 18525

Since you already have the lodash answer here is the ES6 implementation of this via single Array.reduce just so you have to to compare:

var data = [ { 'proyecto': 'barney', 'historia': 42, 'tarea': 'dog' }, { 'proyecto': 'barney', 'historia': 42, 'tarea': 'lion' }, { 'proyecto': 'fred', 'historia': 35, 'tarea': 'dog' }, { 'proyecto': 'barney', 'historia': 41, 'tarea': 'cat' }, { 'proyecto': 'fred', 'historia': 35, 'tarea': 'goldfish' } ];

const result = data.reduce((r, {proyecto, historia, tarea}) => {
  r[proyecto] = r[proyecto] || {proyecto, historia: [], tarea: []}
  r[proyecto].historia.push(historia)
  r[proyecto].tarea.push(tarea)
  return r
}, {})

console.log(Object.values(result))

Since you are using reduce there is no need for the 2nd _.map loop and all can be done in one "shot".

If ES6 is an issue here is the same implementation with _.reduce:

var data = [ { 'proyecto': 'barney', 'historia': 42, 'tarea': 'dog' }, { 'proyecto': 'barney', 'historia': 42, 'tarea': 'lion' }, { 'proyecto': 'fred', 'historia': 35, 'tarea': 'dog' }, { 'proyecto': 'barney', 'historia': 41, 'tarea': 'cat' }, { 'proyecto': 'fred', 'historia': 35, 'tarea': 'goldfish' } ];

const result = _.reduce(data, function(r,c) {
  r[c.proyecto] = r[c.proyecto] || {proyecto: c.proyecto, historia: [], tarea: []}
  r[c.proyecto].tarea.push(c.tarea)
  r[c.proyecto].historia.push(c.historia)
  return r
}, {})

console.log(_.values(result))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

Upvotes: 2

Ori Drori
Ori Drori

Reputation: 193358

Use _.map() to extract the historia (like you do for tarea):

var characters = [
  { 'proyecto': 'barney', 'historia': 42,  'tarea': 'dog' },
  { 'proyecto': 'barney', 'historia': 42,  'tarea': 'lion' },
  { 'proyecto': 'fred',   'historia': 35,  'tarea': 'dog' },
  { 'proyecto': 'barney', 'historia': 41,  'tarea': 'cat' },
  { 'proyecto': 'fred',   'historia': 35,  'tarea': 'goldfish' }
];

var result= _(characters)
  .groupBy("proyecto")
  .map(function(v, i) {
    return {
      proyecto: i,
      historia: _.map(v, 'historia'),
      tarea: _.map(v, 'tarea')
    }
  })
  .value();
  
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

Upvotes: 1

Related Questions