yoonvak
yoonvak

Reputation: 323

alter element in array with html tag, then display that array

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

Answers (2)

xdeepakv
xdeepakv

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

PJohnson
PJohnson

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

Related Questions