因此,对于每个预测,Google Places自动完成API还会为每个预测返回匹配的子字符串。
输入:San 68
预测:旧金山68
匹配的子字符串:[{ offset: 0, length: 3 }, { offset: 15, length: 2 }]
期望:San弗朗西斯科68
我的目标是使用匹配的子字符串突出显示部分预测。现在有一些挑战。我可以使用replace
函数,并用<b>str</b>
替换每个子字符串,但是它返回一个字符串,这意味着除非我使用dangerouslySetInnerHTML
,否则该方法无效。
我也不认为有办法替换多个子字符串。我尝试使用reduce
函数,但是在第一个循环之后,由于索引将是错误的,因此它实际上将无法工作。
const highlight = (text, matched_substrings) => {
return matched_substrings.reduce((acc, cur) => {
return acc.replace(
acc.substring(cur.offset, cur.length),
(str) => `<b>${str}</b>`
)
}, text)
}
所以有办法吗?我认为React使这变得更加复杂。
可能不是最好的解决方案,但绝对可以解决一个问题:)前提条件是,必须按偏移量对matchd_substrigs数组进行排序
export const highlightText = (text, matched_substring, start, end) => {
const highlightTextStart = matched_substring.offset;
const highlightTextEnd = highlightTextStart + matched_substring.length;
// The part before matched text
const beforeText = text.slice(start, highlightTextStart);
// Matched text
const highlightedText = text.slice(highlightTextStart, highlightTextEnd);
// Part after matched text
// Till the end of text, or till next matched text
const afterText = text.slice(highlightTextEnd, end || text.length);
// Return in array of JSX elements
return [beforeText, <strong>{highlightedText}</strong>, afterText];
};
export const highlight = (text, matched_substrings) => {
const returnText = [];
// Just iterate through all matches
for (let i = 0; i < matched_substrings.length; i++) {
const startOfNext = matched_substrings[i + 1]?.offset;
if (i === 0) { // If its first match, we start from first character => start at index 0
returnText.push(highlightText(text, matched_substrings[i], 0, startOfNext))
} else { // If its not first match, we start from match.offset
returnText.push(highlightText(text, matched_substrings[i], matched_substrings[i].offset, startOfNext))
}
}
return returnText.map((text, i) => <React.Fragment key={i}>{text}</React.Fragment>)
};