反应:突出显示两个索引之间的文本

问题描述 投票:0回答:1

因此,对于每个预测,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使这变得更加复杂。

javascript reactjs google-places-api
1个回答
0
投票

可能不是最好的解决方案,但绝对可以解决一个问题:)前提条件是,必须按偏移量对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>)
};
© www.soinside.com 2019 - 2024. All rights reserved.