i am trying to create a function which takes in 2 strings:
- title: "Lorem ipsum dolor sit amet",
- itle_highlighted: "ipsum amet",
and returns one string or array containing the all words in title
in addition words defined in the string title_highlighted
will have a certain property and replace their matching word in title
.
End result should be something like: <h1>Lorem<span style={{color: "orange"}}>impsum</span>dolor sit<span style={{color: "orange"}}>amet</span>/h1>
My approach so far:
const highlightHeading = (title, title_highlighted) => {
const title_arr = title.trim().split(/\s /);
const title_highlighted_arr = title_highlighted.trim().split(/\s /);
for (const element1 of title_arr) {
console.log(element1);
for (const element2 of title_highlighted_arr) {
if (element1 === element2) {
const highlighted = `<span style={{ color: "orange" }}>${element1}</span>`;
console.log(highlighted);
}
}
}
};
highlightHeading("Lorem ipsum dolor sit amet", "ipsum amet");
Thanks in advance.
CodePudding user response:
The naive splitting approach doesn't take punctuation into account (e.g. Lorem ipsum? Dolor amet!
). You can try a regex with a word boundary \b
instead:
title = "Lorem ipsum dolor sit amet"
keywords = ["ipsum", "amet"]
regex = new RegExp('\\b(' keywords.join('|') ')\\b', 'g')
result = title.replace(regex, '<span whatever>$&</span>')
console.log(result)
CodePudding user response:
You could create a <HighlightedHeading>
component that accepts a color
, title
, and words
.
const { useMemo, useState } = React;
const HighlightedHeading = (props) => {
const { color, title, words } = props;
const tokens = title.trim().split(/\s /g);
const wordList = useMemo(
() =>
!Array.isArray(words)
? new Set(words.trim().split(/\s /g))
: new Set(words),
[words]
);
return (
<h2 className="highlighted-text">
{tokens.map((token) =>
wordList.has(token)
? <span style={{ color }}>{token}</span>
: token
)}
</h2>
);
};
const App = () => {
return (
<div>
<HighlightedHeading
color="yellow"
title="Lorem ipsum dolor sit amet"
words="ipsum amet"
/>
</div>
);
};
ReactDOM
.createRoot(document.getElementById("root"))
.render(<App title="Example using Hooks:" />);
*, *::before, *::after {
box-sizing: border-box;
}
html, body, #root {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#root {
background: #222;
color: #FFF;
}
.highlighted-text {
display: flex;
gap: 0.5ch;
margin: 0;
justify-content: center;
}
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>