Need some help please - am using the excellent response to this histogram bucketing question as per code below. My question is what is the most elegant way to get my buckets with zero counts represented in the function output?
Current Output is:
[ [ '0', 2 ],
[ '32', 1 ],
[ '64', 2 ],
[ '80', 1 ],
[ '96', 1 ],
[ '112', 1 ] ]
which omits to note buckets 16 and 48 which have zero counts.
My desired output is:
[ [ '0', 2 ],
[ '16', 0 ],
[ '32', 1 ],
[ '48', 0 ],
[ '64', 2 ],
[ '80', 1 ],
[ '96', 1 ],
[ '112', 1 ] ]
All help much appreciated.
function defArrs (){
var arr = [1,16,38,65,78,94,105,124]
var binsize = 16;
var check = Object.entries(frequencies (arr,binsize));
console.log(check);
}
function frequencies(values, binsize) {
var mapped = values.map(function(val) {
return Math.ceil(val / binsize) -1;
});
console.log(mapped);
return mapped.reduce(function (freqs, val, i) {
var bin = (binsize * val);
freqs[bin] ? freqs[bin]++ : freqs[bin] = 1;
return freqs;
}, {});
}
Instead of starting with the empty object for .reduce
:
}, {});
// ^^
construct one with all the properties you'll want to be included at the end (starting with a count of 0, of course).
const initialObj = Object.fromEntries(
Array.from(
{ length: 7 },
(_, i) => [i * binsize, 0]
)
);
And pass that as the second parameter to .reduce
.
That approach also means that this
freqs[bin] ? freqs[bin]++ : freqs[bin] = 1;
will simplify to
freqs[bin]++;
Or, even better:
const frequencies = (nums, binsize) => {
const mapped = nums.map(num => Math.ceil(num / binsize) - 1;
const grouped = Object.fromEntries(
{ length: 7 },
(_, i) => [i * binsize, 0]
);
for (const val of mapped) {
grouped[binsize * val]++;
}
return grouped;
};