如何在JavaScript直方图频率统计函数中包含零计数
直方图分桶补全零计数桶的优雅实现
当前的直方图分桶统计函数输出中缺少16、48这类零计数的桶,需要调整实现,让输出包含所有应该存在的桶(哪怕计数为0)。
当前代码
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; }, {}); }
当前输出
[ [ '0', 2 ], [ '32', 1 ], [ '64', 2 ], [ '80', 1 ], [ '96', 1 ], [ '112', 1 ] ]
期望输出
[ [ '0', 2 ], [ '16', 0 ], [ '32', 1 ], [ '48', 0 ], [ '64', 2 ], [ '80', 1 ], [ '96', 1 ], [ '112', 1 ] ]
优雅实现方案
核心思路是先预先生成所有需要的桶,再填充计数,确保零计数的桶不会被遗漏:
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) { // 计算最大值对应的最大桶编号 const maxVal = Math.max(...values); const maxBin = binsize * (Math.ceil(maxVal / binsize) - 1); // 初始化所有桶的计数为0 const freqs = {}; for (let bin = 0; bin <= maxBin; bin += binsize) { freqs[bin] = 0; } // 遍历原始值统计频率 values.forEach(val => { const bin = binsize * (Math.ceil(val / binsize) - 1); freqs[bin]++; }); return freqs; }
实现说明
- 通过最大值确定需要覆盖的所有桶范围,用循环预生成每个桶并初始化计数为0,从根源避免遗漏零计数桶。
- 遍历原始数组时,仅需对对应桶的计数进行递增操作,逻辑清晰且高效。
- 最终返回的对象包含所有应存在的桶,经
Object.entries转换后直接得到期望格式的输出。
内容的提问来源于stack exchange,提问作者Swiss23
相关产品推荐
相关产品推荐

