Tag and Category Reducer

by Michael Perrenoud

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<p id="output">

</p>

JavaScript

function reducer(field, target, output, value) {
		var o = _.find(output, { eventId: value.eventId });
  	if (!o) {
    	value[target] = [value[field]];
			delete value[field];
			output.push(value);
    } else {
	    o[target] = _.union(o[target], [value[field]])
    }

		return output;
  };

var data = [
	{ eventId: 1, firstName: 'Mike', tag: 'a', category: 'Concerts' },
	{ eventId: 1, firstName: 'Mike', tag: 'b', category: 'Concerts' },
	{ eventId: 2, firstName: 'Don', tag: 'b', category: 'Concerts' },
	{ eventId: 2, firstName: 'Don', tag: 'c', category: 'Sports' },
	{ eventId: 3, firstName: 'Kelly', tag: 'a', category: 'Concerts' },
	{ eventId: 3, firstName: 'Kelly', tag: 'c', category: 'Sports' },
	{ eventId: 4, firstName: 'Bill', tag: 'a', category: 'Concerts' },
	{ eventId: 4, firstName: 'Bill', tag: 'b', category: 'Concerts' },
	{ eventId: 4, firstName: 'Bill', tag: 'c', category: 'Sports' }
];

var results = _.chain(data)
	.orderBy('eventId')
	.reduce(reducer.bind(null, 'tag', '_tags'), [])
  .value();

console.log('First Results:', results);

results = _.chain(results)
	.orderBy('eventId')
	.reduce(reducer.bind(null, 'category', 'categories'), [])
  .value();

$('#output').html(JSON.stringify(results));