Reputation: 323
I am working on a word frequency app, where the user can find the most used word in the text and alter that word and display an altered version of the whole text in HTML.
I created a function where you create a span
tag around the altered word, so I can give a class to add some CSS to highlight it.
const updatedTextArr = text.map(word => {
const isSameWord = word === mostUsedWord
if (isSameWord) {
const spanNode = document.createElement("span")
const alteredWord = `foo${mostUsedWord}bar`
spanNode.append(alteredWord)
word = spanNode
return word
} else {
return word
}
const createString = updatedTextArr.join(" ").toString()
setTextData(createString)
})
But in this way, when I console.log it, the returned altered word in a text array shows as "HTML element"
and when I display the "createString", it shows altered words as same as "HTML elements" in the view.
I wonder what is the better way to add a span tag to the found most used word?
Upvotes: 0
Views: 50
Reputation: 8135
Using Map
and array.reduce
you can solve this problem.
const highlight = (text = "") => {
const words = text.split(/\W/g);
const wordMap = words.reduce((m, word) => {
if (!m[word]) m[word] = 0;
m[word] = (m[word] || 0) + 1;
return m;
}, {});
let mostUsedWord = { count: 0, word: "" };
for (let word in wordMap) {
if (mostUsedWord.count < wordMap[word]) {
mostUsedWord = { count: wordMap[word], word };
}
}
return words.map(word => {
if (word === mostUsedWord.word) {
word = `<span class="highlighted">${word}</span>`;
}
return word;
});
};
const createString = highlight(
"This is a book of life. Which is never found in the jungle."
).join(" ");
console.log(createString);
document.getElementById("app").innerHTML = createString
.as-console-row {color: red!important}
.highlighted {color: red!important}
<div id="app"></div>
Upvotes: 1
Reputation: 180
Your last two lines are inside the function, they should be outside. If you want the entire element as text, you can use outerHTML
. Also, no need for an else
statement since you return the word in any case.
const updatedTextArr = text.map( word => {
const isSameWord = word === mostUsedWord
if ( isSameWord ) {
const spanNode = document.createElement( "span" )
const alteredWord = `foo${ mostUsedWord }bar`
spanNode.append( alteredWord )
word = spanNode.outerHTML
}
return word
} )
const createString = updatedTextArr.join( " " ).toString()
setTextData( createString )
This would return something like "one <span>footwobar</span> three"
(if most used word is two).
Upvotes: 1