如何实现含占位符字符串与多词集的全组合生成?
解决占位符全组合替换的问题
看起来你现在的代码只是逐个替换单个占位符,所以只能得到部分替换的结果——要生成所有占位符都被替换的完整组合,核心是要计算不同词集之间的笛卡尔积,然后把每个组合对应替换到模板里。我来帮你调整代码,实现这个需求:
第一步:明确数据映射关系
首先你需要把占位符和对应的词集做一个清晰的映射,比如针对你第二个例子:
// 假设你的elements可以整理成这样的映射(如果不是,先转成这个结构) const placeholderMap = { "{{animal}}": ["cat", "dog", "iguana", "bird"], "{{country}}": ["usa", "mexico", "denmark"], "{{cost}}": ["cheap", "expensive", "good", "price"] }; // 你的模式数组 const patterns = ["{{animal}} in {{country}} for {{cost}}"];
第二步:实现笛卡尔积生成函数
我们需要一个函数来计算多个数组的笛卡尔积,这是生成所有组合的关键:
// 生成笛卡尔积的工具函数 const cartesianProduct = (...arrays) => { return arrays.reduce((acc, curr) => { return acc.flatMap(accItem => { return curr.map(currItem => [...accItem, currItem]); }); }, [[]]); };
第三步:修改你的generateKeywords函数
调整逻辑,先提取每个模板的占位符,计算对应词集的笛卡尔积,再批量替换:
generateKeywords() { // 1. 先整理占位符到词集的映射(如果你的elements不是这个结构,先转换) const placeholderMap = {}; this.elements.forEach(element => { placeholderMap[element.element_caught] = element.list_of_variations.split('\n'); }); // 2. 拆分模式数组 const patternArray = this.patterns.split(','); const fullCombinations = []; patternArray.forEach(pattern => { // 3. 提取当前模板里的所有占位符(正则根据你的占位符格式调整) // 比如你的第一个例子用 /\[\w+\]/g,第二个例子用 /{{\w+}}/g const placeholders = [...new Set(pattern.match(/{{\w+}}/g))]; // 4. 获取每个占位符对应的词集 const wordSets = placeholders.map(ph => placeholderMap[ph]); // 5. 计算笛卡尔积,得到所有词的组合 const product = cartesianProduct(...wordSets); // 6. 把每个组合替换到模板里 product.forEach(combination => { let result = pattern; placeholders.forEach((ph, index) => { result = result.replace(new RegExp(ph, 'g'), combination[index]); }); fullCombinations.push(result); }); }); return fullCombinations; }
关键逻辑说明
- 笛卡尔积:比如你有3个词集,每个词集有4、3、4个元素,笛卡尔积会生成
4*3*4=48种完整组合,正好对应所有占位符都替换的结果。 - 占位符匹配:注意正则要和你的占位符格式匹配——如果是
[foo]这种格式,就把正则改成/\[\w+\]/g;如果是{{animal}}就用/{{\w+}}/g。 - 去重占位符:用
new Set确保每个占位符只处理一次,避免重复替换。
用你第一个测试例子来验证的话,输入:
const placeholderMap = { "[foo]": ["a","b","c"], "[bar]": ["d","e","f"] }; const patterns = ["[foo] is a [bar]", "[foo] is not a [bar]", "[foo] could be a [bar]"];
运行后会生成3*3*3=27条完整的句子,比如"a is a d"、"a is a e"..."c could be a f",完全符合你的需求。
内容的提问来源于stack exchange,提问作者Vargas Rickky
相关产品推荐
相关产品推荐

