For example: "Today, is the greatest day ever!" should return greatest because it has 2 e's (and 2 t's) and it comes before ever which also has 2 e's. If there are no words with repeating letters return -1. Words will be separated by spaces. Input:"Hello Apple Pie" Output should be:"Hello" Do not understand what is wrong with my code, also if you think there is a simpler and shorter way to solve I would love to hear it. Thanks in advance for the help.
function LetterCountI(str) {
let unique=[... new Set(str)]
if(unique==str){
return -1}
let arr= str.split(" ")
let array=arr.map(item=>{
let temparr=item.split("")
return temparr.reduce((acc,curr)=>{
acc[curr]=acc[curr]? acc[curr] 1:1
if(acc[curr]>acc.max){
acc.max=acc[curr]}
return acc},{max:1, word:item})})
let amount=1
let largest=""
for(let item of arr){
if( item.max>amount){
amount=item.max
largest=item.word
}
}
return largest
}
CodePudding user response:
Start with the simpler problem of getting the frequency of each letter in a word...
// given "sassy", will return { s:3, a:1, y:1 }
function letterFrequency(word) {
return word.split('').reduce((acc, letter) => {
if (!acc[letter]) acc[letter] = 0;
acc[letter] ;
return acc;
}, {});
}
A simple problem to get the max frequency...
// given { s:3, a:1, y:1 }, will return 3
function maxLetterFrequency(word) {
return Math.max(...Object.values(letterFrequency(word)));
}
Another simple problem to sort a sentence by frequency...
// given "She sells seashells by the seashore"
// returns ["seashells", "sells", "seashore", "She", "by", "the"]
function wordsOrderedByMaxLetterFrequency(sentence) {
let words = sentence.split(' ');
words.sort((a, b) => {
return maxLetterFrequency(b) - maxLetterFrequency(a);
});
return words;
}
The first word in the resulting array is the answer. You can retest max frequencies in that word to determine of the answer should be -1.
Demo...
// given "sassy", will return { s:3, a:1, y:1 }
function letterFrequency(word) {
return word.split('').reduce((acc, letter) => {
if (!acc[letter]) acc[letter] = 0;
acc[letter] ;
return acc;
}, {});
}
// given { s:3, a:1, y:1 }, will return 3
function maxLetterFrequency(word) {
return Math.max(...Object.values(letterFrequency(word)));
}
// given "She sells seashells by the seashore"
// returns ["seashells", "sells", "seashore", "She", "by", "the"]
function wordsOrderedByMaxLetterFrequency(sentence) {
let words = sentence.split(' ');
words.sort((a, b) => {
return maxLetterFrequency(b) - maxLetterFrequency(a);
});
return words;
}
const sentence = "She sells seashells by the seashore";
const sorted = wordsOrderedByMaxLetterFrequency(sentence);
console.log(sorted);
console.log('best word:', sorted[0]);
console.log('max freq in best word:', maxLetterFrequency(sorted[0]));
CodePudding user response:
Staying with the OP's reduce
based approach one would provide a single function which incorporates two specific nested reduce
tasks responsible for 1) aggregating the word specific statistics of a sentence and 2) the letter specific statistics for each word.
This approach also ensures the result of ''
(suggested) or -1
(the OP'S requirement) in case there are only words of unique (non repeating) letters/characters.
function getFirstOccurringWordOfMaximumSameCharacterCount(value) {
function aggregateCharCountData(wordStats, char, idx, arr) {
const { charStats } = wordStats;
// aggregate character specific array.
(charStats[char] ??= []).push(char);
if (idx >= (arr.length - 1)) {
// console.log({ charStats });
// aggregate maximum character count data
// at the end of the last character reduce step.
const maxCharList = Object
.values(charStats)
.sort((aCharList, bCharList) =>
bCharList.length - aCharList.length
)[0];
wordStats.maxCharCount = maxCharList.length;
wordStats.maxCountChar = maxCharList[0];
}
return wordStats;
}
function aggregateWordSpecificCharCountData(collector, word, idx, arr) {
const { statistics } = collector;
statistics.push(
word
.split('')
.reduce(aggregateCharCountData, { word, charStats: {} })
);
if (idx >= (arr.length - 1)) {
// find the first occurring word of maximum same character count
// at the end of the last word reduce step.
const wordStats = statistics
.sort((aWordStats, bWordStats) =>
bWordStats.maxCharCount - aWordStats.maxCharCount
)[0];
// console.log({ statistics });
collector.result = (wordStats.maxCharCount >= 2)
? wordStats.word
: ''; // : -1;
}
return collector;
}
const {
// statistics,
result,
} = String(value)
.split(/\s /)
.reduce(aggregateWordSpecificCharCountData, {
statistics: [],
result: '',
});
// console.log({ statistics });
return result;
}
console.log([
'Today is the day.', // ''
'Today, is the greatest day ever!', // 'greatest'
'Hello Apple Pie', // 'Hello'
'She sells seashells by the seashore' // 'seashells'
].map(getFirstOccurringWordOfMaximumSameCharacterCount));
.as-console-wrapper { min-height: 100%!important; top: 0; }