I am writing a function that returns an array of how many times each letter of the alphabet (az) occurs in a string, including 0. This array only contains 26 numbers. So far this is the function I've come up with. It works, but I feel like must be a cleaner way to refactor this solution.
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)
}
Since you're using ES6, let's try extending Map
with some additional functionality to make this straightforward. We'll add an update()
function for semantically incrementing, and a get()
function that returns a default value (for example, 0
), if the key does not exist on the map yet:
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 az const validChars = Array.from( {length: 26}, (value, index) => String.fromCharCode(index + initialCharCode) ) function generateMap (text) { const chars = text.replace(/[^az]/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.'))
We then define the validChars
a single time, statically, outside the function generateMap()
since we only need to do that once. We also get our array by mapping validChars
rather than calling Object.values()
on the map
, so that iteration order is guaranteed by specification rather than implementation.
Edit:
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()
on valid_char
is a warranty.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.