I've just read about reactive programming and I am enthusiast about it. So I decided to revise my skill on functional programming. I don't know if this is the right place.
I have two array, one of tags and one of tasks that contains tags. I'd like to aggregate the two and go out with a tasksByTagName. I've tried to use lodash but I didn't managed to do it in a readable way so I'm posting what I've done with normal for statements.
More over I'm interested in understanding how to think in a flow based way, such as thinking my aggregate function as a transformation between two stream, as the reactive programming article linked above suggest.
So, let's start with datas:
var tags = [
{ id: 1, name: 'Week 26' },
{ id: 2, name: 'week 27' },
{ id: 3, name: 'Week 25' },
{ id: 4, name: 'Week 25' }
];
var tasks = [
{
"name": "bar",
"completed": false,
"tags": [
{ "id": 1 },
{ "id": 2 }
]
},
{
"name": "foo",
"completed": true,
"tags": [
{ "id": 1 }
]
},
{
"name": "dudee",
"completed": true,
"tags": [
{ "id": 3 },
{ "id": 1 },
{ "id": 4 }
]
}
];
And this is my piece of code:
var _ = require('lodash');
function aggregate1(tasks, tags) {
var tasksByTags = {};
for(var t in tasks) {
var task = tasks[t];
for(var i=0; i<task.tags.length; ++i) {
var tag = task.tags[i];
if( !tasksByTags.hasOwnProperty(tag.id) ) {
tasksByTags[tag.id] = [];
}
tasksByTags[tag.id].push(task.name);
}
}
var tagById = {};
for(var t in tags) {
var tag = tags[t];
tagById[tag.id] = tag.name;
}
var tasksByTagsName = _.mapKeys(tasksByTags, function(v, k) {
return tagById[k];
})
return tasksByTagsName;
}
module.exports.aggregate1 = aggregate1;
For completeness, this is also the test with test data:
var tags = [
{ id: 1, name: 'Week 26' },
{ id: 2, name: 'week 27' },
{ id: 3, name: 'Week 25' },
{ id: 4, name: 'Week 25' }
];
var tasks = [
{
"name": "bar",
"completed": false,
"tags": [
{ "id": 1 },
{ "id": 2 }
]
},
{
"name": "foo",
"completed": true,
"tags": [
{ "id": 1 }
]
},
{
"name": "dudee",
"completed": true,
"tags": [
{ "id": 3 },
{ "id": 1 },
{ "id": 4 }
]
}
];
var goodResults1 = {
'Week 26': [ 'bar', 'foo', 'dudee' ],
'week 27': [ 'bar' ],
'Week 25': [ 'dudee' ]
};
var assert = require('assert')
var aggregate1 = require('../aggregate').aggregate1;
describe('Aggegate', function(){
describe('aggregate1', function(){
it('should work as expected', function(){
var result = aggregate1(tasks, tags);
assert.deepEqual(goodResults1, result);
})
})
})
goodResultsis dead code since it's not used anywhere. The unit test usesgoodResults1.