我正在编写一个函数,它返回一个字符串中每个字母(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)
}
答案 0 :(得分:1)
由于您使用的是ES6,让我们尝试使用其他一些功能来扩展Map
以简化这一过程。我们将添加一个用于语义递增的update()
函数,以及一个返回默认值的get()
函数(例如,0
),如果地图上尚不存在该键:
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.'))
然后,我们在函数validChars
之外静态定义generateMap()
一次,因为我们只需要执行一次。我们也通过映射validChars
来获取我们的数组,而不是在Object.values()
上调用map
,因此迭代顺序由规范而不是实现来保证。
答案 1 :(得分:0)
修改强>
export function generateMap(text){
var text_arr = text.toLowerCase().split('').sort();
const valid_char = 'abcdefghijklmnopqrstuvwxyz'.split('').sort();
const map = {};
valid_char.forEach(char => {
var count = text_arr.lastIndexOf(char) + 1;
text_arr = text_arr.slice(count);
map[char] = count;
});
return Object.values(map)
}
sort()
上的{p> valid_char
是保修。