简体   繁体   中英

Map of alphabet - how many times each letter occurs in a string (including 0)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM