在Javascript中如何基于两个数组生成对应首字母词频数组
问题原因
你现有的代码每次循环都会直接覆盖frequency变量的值,因此最终只会保留最后一个字母对应的单词统计数,无法得到完整数组。
最优写法(优先推荐,可读性最高)
对于这个需求,直接使用Array.prototype.map是最适配的语法:map可以直接将alphabet数组的每一项映射为对应字母的统计值,最终返回和alphabet长度一致、索引完全对应的frequency数组,不需要手动维护索引:
const frequency = alphabet.map(letter => dictionary.filter(item => item.word.toLowerCase().startsWith(letter)).length );
这种写法逻辑清晰代码简洁,在dictionary数据量不大的场景下是最优选择。
大数据量优化方案
如果dictionary的条目非常多,上述写法每次filter都会全量遍历一次dictionary,时间复杂度为O(字母表长度 * 字典长度),可以优化为先做一次全量统计再生成结果,只需要遍历一次字典:
// 第一步:统计所有单词首字母的出现次数 const firstLetterCount = {}; dictionary.forEach(item => { const firstLetter = item.word.toLowerCase()[0]; firstLetterCount[firstLetter] = (firstLetterCount[firstLetter] || 0) + 1; }); // 第二步:按字母表顺序生成frequency数组,无对应单词的字母默认值为0 const frequency = alphabet.map(letter => firstLetterCount[letter] || 0);
优化后的时间复杂度为O(字母表长度 + 字典长度),数据量越大性能优势越明显。
其他可选写法说明
你提到的手动维护forEach索引的方式也可以实现,但语法冗余度更高,没有使用map简洁,不推荐:
const frequency = []; alphabet.forEach(letter => { const count = dictionary.filter(item => item.word.toLowerCase().startsWith(letter)).length; frequency.push(count); });
内容的提问来源于stack exchange,提问作者Cirrocumulus
相关产品推荐
相关产品推荐

