修改LeftJoin函数:将精确匹配改为包含匹配(JS/Google Apps Script)
修改leftJoin函数实现包含匹配
原leftJoin函数通过精确匹配指定列合并两个数组,原测试代码及运行结果如下:
function test() { let a =[ ['aH1','aH2','aH3','aH4'], ['a','B','c','d'], ['x','R','l','a'], ['t','R','g','m'], ['t','A','g','m'] ]; let b =[ ['bH1','bH2','bH3'], ['A','ZZ','XX'], ['R','YY','RR'], ['t','GG','QQ'] ]; const result = leftJoin(a, b, "aH2", "bH1") console.log(result) // 运行结果: // result = [ // [ 'aH1', 'aH2', 'aH3', 'aH4', 'bH2', 'bH3' ], // [ 'a', 'B', 'c', 'd', '', '' ], // [ 'x', 'R', 'l', 'a', 'YY', 'RR' ], // [ 't', 'R', 'g', 'm', 'YY', 'RR' ], // [ 't', 'A', 'g', 'm', 'ZZ', 'XX' ] // ] }
现在数组b的匹配列改为用|分隔的字符串(如H|A|1|L包含A),修改后的b数组:
let b =[ ['bH1','bH2','bH3'], ['H|A|1|L','ZZ','XX'], ['|D|K|R','YY','RR'], ['t|S|G','GG','QQ'] ];
修改方案
核心是重构构建匹配映射表(temp)的逻辑,将b匹配列的字符串拆分后,把每个有效子串作为键关联到对应行。修改后的完整函数如下:
function leftJoin(a, b, akey, bkey) { akey = akey.toLowerCase(); bkey = bkey.toLowerCase(); const without = ([...array], index) => (array.splice(index, 1), array); const aIndex = a[0].findIndex(s => s.toLowerCase() === akey); const bIndex = b[0].findIndex(s => s.toLowerCase() === bkey); // 重构temp:将b匹配列按|拆分,每个有效子串映射到对应行 const temp = b.slice(1).reduce((r, items) => { // 拆分字符串并过滤空串(处理开头/结尾的|) const matchValues = items[bIndex].split('|').filter(val => val.trim() !== ''); matchValues.forEach(val => { // 仅保留第一个匹配的b行,避免后续行覆盖 if (!r[val]) { r[val] = items; } }); return r; }, {}); return a.map((row, i) => [ ...row, ...without( i ? temp[row[aIndex]] || Array(b[0].length).fill('') : b[0], bIndex ) ]); }
关键修改说明
- 重构
temp映射表:- 不再用b匹配列的完整字符串作为键,而是将其按
|拆分,过滤掉空串(处理类似|D|K|R这种首尾带|的情况)。 - 遍历拆分后的每个有效子串,将其作为键存入
temp,并关联到当前b行;如果同一个子串对应多个b行,仅保留第一个匹配的行(避免覆盖)。
- 不再用b匹配列的完整字符串作为键,而是将其按
- 匹配逻辑复用:原函数的查找逻辑无需改动,直接用a行的匹配值去
temp中查找对应的b行,找不到则返回空值填充的数组。
运行修改后的函数,新的测试结果符合预期:
// 运行结果: [ [ 'aH1', 'aH2', 'aH3', 'aH4', 'bH2', 'bH3' ], [ 'a', 'B', 'c', 'd', '', '' ], [ 'x', 'R', 'l', 'a', 'YY', 'RR' ], [ 't', 'R', 'g', 'm', 'YY', 'RR' ], [ 't', 'A', 'g', 'm', 'ZZ', 'XX' ] ]
内容的提问来源于stack exchange,提问作者Einarr
相关产品推荐
相关产品推荐

