我正在编写一个函数,该函数返回一个数组,其中包含字母表中的每个字母 (a-z) 在字符串中出现的次数(包括 0)。该数组仅包含 26 个数字。到目前为止,这是我想出的功能。它有效,但我觉得必须是重构此解决方案的更简洁的方法。
export function generateMap(text){
const text_arr = text.toLowerCase().split('');
const valid_char = 'abcdefghijklmnopqrstuvwxyz'.split('')
const map = {'a': 0, 'b': 0, 'c': 0, 'd': 0, 'e': 0, 'f': 0, 'g': 0, 'h': 0, 'i': 0, 'j': 0, 'k': 0, 'l': 0, 'm': 0, 'n': 0, 'o': 0, 'p': 0, 'q': 0, 'r': 0, 's': 0, 't': 0, 'u': 0, 'v': 0, 'w': 0, 'x': 0, 'y': 0, 'z': 0}
text_arr.forEach(char => {
if(valid_char.indexOf(char) > -1) map[char]++
})
return Object.values(map)
}
最佳答案
由于您使用的是 ES6,让我们尝试使用一些附加功能来扩展 Map
,以使此过程变得简单。我们将添加一个用于语义递增的 update()
函数,以及一个返回默认值的 get()
函数(例如 0
),如果 map 上尚不存在该键:
class DefaultMap extends Map {
constructor (defaultValue, iterable = []) {
super(iterable)
this.default = defaultValue
}
get (key) {
if (this.has(key)) {
return super.get(key)
}
return this.default
}
update (key, fn) {
this.set(key, fn(this.get(key)))
}
}
const initialCharCode = 'a'.charCodeAt(0)
// generate the valid characters from the ASCII table a-z
const validChars = Array.from(
{length: 26},
(value, index) => String.fromCharCode(index + initialCharCode)
)
function generateMap (text) {
const chars = text.replace(/[^a-z]/gi, '').toLowerCase().split('')
const map = new DefaultMap(0)
chars.forEach(char => map.update(char, count => count + 1))
return validChars.map(validChar => map.get(validChar))
}
console.log(generateMap('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'))
然后,我们在函数 generateMap()
之外静态地定义一次 validChars
,因为我们只需要执行一次。我们还通过映射 validChars
来获取数组,而不是在 map
上调用 Object.values()
,这样迭代顺序是由规范保证的,而不是比实现。
关于javascript - 字母表图 - 每个字母在字符串中出现的次数(包括 0),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46855646/