如何实现不受匹配项顺序影响的字符串拆分并转为数组?
问题描述
需要将原始字符串按照指定的关键词数组拆分为包含分隔符的片段数组,要求无论关键词数组的顺序如何,都能正确得到目标结果。
原始字符串:
let allString = 'This is the test to replace the string';
目标关键词数组(两种顺序):
顺序1:
let toReplace = [ { string: 'the test' }, { string: 'replace' }, ]
顺序2:
let toReplace = [ { string: 'replace' }, { string: 'the test' }, ]
期望结果:
[ 'This is ', 'the test', ' to ', 'replace', ' the string' ]
现有实现代码:
const processedText = toReplace .reduce( (result, { string }, index) => { const parts = result[result.length - 1].split(string); const [before, after] = parts; const newResult = result.slice(); const firstPass = index === 0; if (firstPass) { newResult.shift(); } else { newResult.pop(); } if (before) { newResult.push(before); } if (string) { newResult.push(string); } if (after) { newResult.push(after); } return newResult; }, [allString] )
问题:当调整关键词数组顺序后,代码无法正确拆分,会出现错误结果(如顺序2时得到[ 'This is the test to ', 'replace', ' the string', 'the test' ])。
解决方案
问题分析
原代码的核心缺陷是每次仅处理结果数组的最后一项,当后续关键词不在最后一项中时,无法找到匹配项,反而会错误地将关键词直接追加到结果数组末尾。
修正后的代码
const processedText = toReplace.reduce((result, { string }) => { // 遍历当前结果数组,对每个片段检查是否需要拆分 return result.flatMap(item => { // 如果当前片段不包含目标字符串,直接返回原片段 if (!item.includes(string)) { return [item]; } // 拆分片段,保留分隔符 const parts = item.split(string); // 把拆分后的部分和分隔符交替组合 return parts.flatMap((part, idx) => { const res = []; if (part) res.push(part); // 不是最后一个拆分部分的话,添加分隔符 if (idx !== parts.length - 1) res.push(string); return res; }); }); }, [allString]);
代码说明
- 使用
flatMap遍历当前结果数组的每个片段,确保所有片段都被检查到,而非仅最后一项。 - 对每个片段,先判断是否包含目标关键词:
- 不包含则直接保留原片段;
- 包含则拆分片段,然后将拆分后的前后部分与关键词交替组合(确保关键词被保留在结果中)。
- 无论关键词数组的顺序如何,都会对所有已有的片段进行全面检查,保证拆分逻辑的正确性。
内容的提问来源于stack exchange,提问作者Khant
相关产品推荐
相关产品推荐

