# Calculate percentage with lodash

I have data like:

var data =
[{
"date":"1-1-2013",
},{
"date":"1-1-2013",
},{
"date":"2-1-2013",
},{
"date":"2-1-2013",
},{
"date":"2-1-2013",
},,{
"date":"2-1-2013",
}];


I need to return[array] percentages of responses for that day(groupedBy) which have a value of “yes” for the “answer”.

For above the result is: [50, 0...]

I have written this below code, it works but i believe it can be simplified a lot.

var freshData =  _.map(data,function(key){
if (key.answer == "") return false;
return key;

});

var reducedData = _.filter(freshData, function(n) {
return n != false;
});

var groups = _.groupBy(reducedData, function(value){
return value.date + '#' + value.answer;
});

var result = _.map(groups,function(key){
if (key[0].answer == "") return false;
return {
date : key[0].date,
length :key.length
};
});

var result2 = _.chunk(result,2);

var result3 =  _.map(result2,function(key){
return {
date:key[0].date,
yes:key[0].length,
no:key[1].length,
percentage : (key[1].length/(key[0].length + key[1].length) * 100)
}
});

var result4 =  _.map(result3,function(key){
return  key.percentage;
});

console.log(result4);


I need to use lodash. Thanks.

solution with lodash:

var data = [{
"date": "1-1-2013",
}, {
"date": "1-1-2013",
}, {
"date": "2-1-2013",
}, {
"date": "2-1-2013",
}, {
"date": "2-1-2013",
"answer": " " //this is not answered!
}, {
"date": "2-1-2013",
}];

//var grouped = _.groupBy(data, 'date');
var all = _.map(_.groupBy(data, 'date'), function (item, key) {
console.log(key);
var size = item.length,
obj={};
var positiveCount = _.countBy(item, function (i) {
return i.answer == "yes" ? "yes" : "no";
});
var percentagePossitive = (positiveCount.yes / size) * 100;
obj[key] = percentagePossitive || 0;
return obj;
});

console.log(all)


Create a lodash chain, use _.groupBy() to get a dates map, and then reduce it to percentages:

function getNumOfYes(data) {
return _(data).groupBy('date').reduce(function(percentage, answers) {
var numOfYes = _.countBy(answers, 'answer').yes || 0;
percentage.push(numOfYes / answers.length * 100);
return percentage;
}, []);
}

var data = [{
"date": "1-1-2013",
}, {
"date": "1-1-2013",
}, {
"date": "2-1-2013",
}, {
"date": "2-1-2013",
}, {
"date": "2-1-2013",
"answer": " " //this is not answered!
}, , {
"date": "2-1-2013",
}];

var numOfYes = getNumOfYes(data);

console.log(numOfYes);

document.getElementById('results').innerText = JSON.stringify(numOfYes);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>

<pre id="results"></pre>

You can utilize a temporary object for counting and returns an array of objects with date and percentage.

var data = [{
"date": "1-1-2013",
}, {
"date": "1-1-2013",
}, {
"date": "2-1-2013",
}, {
"date": "2-1-2013",
}, {
"date": "2-1-2013",
"answer": " "       //this is not answered!
}, , {
"date": "2-1-2013",
}];

function getPercentage(data) {
var obj = {};
data.forEach(function (a) {
obj[a.date] = obj[a.date] || { yes: 0, no: 0 };
}
});
return Object.keys(obj).map(function (k) {
return {
date: k,
percent: obj[k].yes * 100 / (obj[k].yes + obj[k].no)
};
});
}
document.write('<pre>' + JSON.stringify(getPercentage(data), 0, 4) + '</pre>');

Answer in JS fiddle (check console)

Note, I've used Lodash, but you don't really need it to this :-)

var sortedResults = {}; // create empty object

/**
* sort all the answers on date
*/
_.map(data, function(val){
if(typeof val !== 'undefined'){ // check if not undefined
if(val.answer==='yes' || val.answer==='no'){ // should be yes or no
if (typeof(sortedResults[val.date]) === 'undefined') {
sortedResults[val.date] = []; // if data is not available, add it as an array
}
sortedResults[val.date].push(val.answer); // push the answer to the array
}
}
});

/**
* Calculate the percentages of 'yes'
*/
_.map(sortedResults, function(val, key){
var percentage    = val.length, // get total length
percentageYes = 0; // before map function percentage = 0
_.each(val, function(singleVal){
if(singleVal === 'yes'){ percentageYes++; }
});
sortedResults[key] = { yesPercent: percentageYes / percentage * 100 };
});

/**
* Percentage is available in sortedResults;
*/
console.log(sortedResults);