Home > Software design >  How to proper use reduce() javascript/typescript
How to proper use reduce() javascript/typescript

Time:08-19

  1. I try to solve task below with reduce() and actually the result is ok. But I don't know how to use acc in reduce() instead of acc1 or indexMax.
  2. How to apply typescript to this task.

The task: Find first word with max repeated letter count. For example rrrtygggg and ttbvfddjklyyyaseqq - the winner is rrrtygggg. If sequence has no repeated letters return 'false'. Count only letters, ignor digits and special chars.

Here is my solution. Also I need to keep time complexity not higher than n. The most important part for me is reduce() and acc.

const maxLettersInString =(str)=>{
        let acc1={};
        let indexMax;
        let ind=0;
        let n=0;

        const newStr = str.replace(/[^a-z\s]/gi,'')
        const arr = str.split(' ');
        if(arr.length===0) return false;
        const arr1 = newStr.split('');

        const result = arr1.reduce((acc,x)=>{
            if(x!==' '){
                acc1[x] ? acc1[x]   : acc1[x] = 1;
                if(acc1[x]>n) n=acc1[x], indexMax=ind;
            }
            if(x===' ') acc1={}, ind =1;
            else return indexMax;
        })

        if(n===1) return false
        return arr[result]
    }
console.log(maxLettersInString('fdsJJHHBldfkfd  =dfsfds tbrlllLLtrbtrbrLL666667777LLtlllllll----- fdsfs66df7758 tRbrerbrrtRR'));

CodePudding user response:

Iterate over the original words, with two outer variables:

  • One with a count of the maximum number of repeated letters found so far (starts at 0), and
  • The string corresponding to the count found above

All you need is a simple loop - on each iteration, calculate the repeat count for the current word being iterated over, and if it's higher than the record so far, reassign the two outer variables.

const getRepeatCount = (str) => {
    const repeatCounts = {};
    for (const char of str.replace(/[^a-z]/gi, '')) {
        repeatCounts[char] = (repeatCounts[char] ?? -1)   1;
    }
    return Math.max(...Object.values(repeatCounts));
};
const maxLettersInString = (str) => {
    let maxRepeatsFoundSoFar = 0;
    let bestWordSoFar = '';
    for (const word of str.split(' ')) {
        const repeatCount = getRepeatCount(word);
        if (repeatCount > maxRepeatsFoundSoFar) {
            maxRepeatsFoundSoFar = repeatCount;
            bestWordSoFar = word;
        }
    }
    return bestWordSoFar === '' ? false : bestWordSoFar;
};
console.log(maxLettersInString('rrrtygggg and ttbvfddjklyyyaseqq'));

To turn it into TypeScript, just add : string to the parameter types and : Record<string, number> to the repeatCounts object.

This would be possible to do with .reduce if the accumulator was an object with two properties, maxRepeatsFoundSoFar and bestWordSoFar instead of outer variables - but the typing and syntax noise would be annoying, outer variables are easier.

  • Related