0

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?

2
  • So you return from the function? How are the last two lines going to be executed? Commented Mar 25, 2020 at 19:31
  • I can see unreachable code in the snippet. Commented Mar 25, 2020 at 19:31

2 Answers 2

1

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>

Sign up to request clarification or add additional context in comments.

Comments

1

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).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.