-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrankingService.js
65 lines (51 loc) · 1.56 KB
/
rankingService.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
var _ = require('underscore');
var currentRanks = [];
var currentRanksInvalidated = true;
var itemScore = function(item) {
return (_.size(item.priorities) * _.size(item.priorities)) / _.reduce(item.priorities, function(memo, priority) {
return memo + priority;
}, 0);
};
var rankedScores = function(items) {
var scores = {};
_.chain(items).filter(function(item) {
return _.size(item.priorities) > 0;
}).each(function(item) {
scores[itemScore(item)] = -1;
}).value();
_.chain(_.keys(scores)).sortBy(function(score) {
return score;
}).reverse().each(function(score, index) {
scores[score] = index;
}).value();
return scores;
};
var itemPriorities = function(userRankings) {
var items = {};
_.each(userRankings, function(rankings, userId) {
_.each(rankings, function(item, rank) {
items[item.id] = items[item.id] || _.clone(item);
items[item.id].priorities = items[item.id].priorities || {};
items[item.id].priorities[userId] = rank;
})
});
return _.values(items);
}
exports.getRankedItems = function(userRankings) {
if (!currentRanksInvalidated) return currentRanks;
var items = itemPriorities(userRankings);
var scores = rankedScores(items);
var rankedItems = _.chain(items).filter(function(item) {
return _.size(item.priorities) > 0;
}).map(function(item) {
var score = itemScore(item);
return _.extend({}, item, {
score: score,
rank: scores[score]
});
}).value();
return rankedItems;
};
exports.invalidate = function() {
currentRanksInvalidated = true;
};