JavaScript行列表值对比替换异常问题求助
问题分析与解决方案
问题诊断
你的代码不符合预期的核心原因有三点:
- 重复匹配取同一索引:
iArr.findIndex()每次仅返回iArr中第一个匹配当前lRow的元素索引,导致lArr中重复的博物馆行(比如两个ALPINES MUSEUM DAV)都会取iArr2中同一个位置的元素,无法实现依次替换不同条目。 - iArr2结构未处理:
iArr2的每个元素是单个逗号分隔的字符串,未拆分为可匹配的字段,无法直接和lArr的行进行关联。 - 无替换条目计数机制:没有维护每个博物馆可用替换条目的使用状态,无法实现逐个取用对应馆的不同替换行。
解决方案
通过分组预处理iArr2 + 遍历计数替换的方式解决问题,具体步骤如下:
- 预处理
iArr2,将每个字符串拆分为数组,并按博物馆名称分组,存储每个馆的所有可用替换条目。 - 遍历
lArr时,先判断当前行是否属于iArr允许的博物馆:- 如果是,从对应馆的替换列表中取出第一个条目(取出后从列表中移除,确保下一次取新条目);
- 如果不是,返回预设的
NONE数组。
完整代码
//liste compléte const lArr = [ ['ALPINES MUSEUM DAV','0','0','0','0'], ['ALPINES MUSEUM DAV','0','0','0','0'], ['ARROMANCHES','0','0','0','0'], ['BELVEDERE MUSEUM','0','0','0','0'], ['BELVEDERE MUSEUM','0','0','0','0'], ['BELVEDERE MUSEUM','0','0','0','0'], ['BELVEDERE MUSEUM','0','0','0','0'], ['BELVEDERE MUSEUM','0','0','0','0'], ['BERGBAUMUSEUM OELSNITZ','0','0','0','0'], ['BERGBAUMUSEUM OELSNITZ','0','0','0','0'] ]; //liste des config autorisées const iArr = [ ['ALPINES MUSEUM DAV','0','0','0','0'], ['ARROMANCHES','0','0','0','0'], ['BERGBAUMUSEUM OELSNITZ','0','0','0','0'], ]; //list des choses qui remplacent const iArr2 = [ ['ALPINES MUSEUM DAV, 2D, "MAREIKE", 50, 33.0'], ['ALPINES MUSEUM DAV, PROJECT MANAGEMENT, SOLENN, 50, 23.5'], ['ARROMANCHES, PROJECT MANAGEMENT, NICOLAS, 50, 6.0'], ['BELVEDERE MUSEUM, FABRICATION, CAMILLE, 50, 6.0'], ['BELVEDERE MUSEUM, PROJECT MANAGEMENT, ALEXANDRA, 50, 2.0'], ['BELVEDERE MUSEUM, PROJECT MANAGEMENT, LOUISE, 50, 3.75'], ['BELVEDERE MUSEUM, 2D, JULIEN, 50, 31.5'], ['BELVEDERE MUSEUM, 2D, MARTINA, 50, 4.0'], ['BERGBAUMUSEUM OELSNITZ, FABRICATION, ZELIE, 50, 4.0'], ['BERGBAUMUSEUM OELSNITZ, FABRICATION, CAMILLE, 50, 4.5'] ]; // 1. 预处理iArr2:拆分字符串并按博物馆名称分组 const replacementMap = iArr2.reduce((map, item) => { // 拆分单个字符串为数组,避免拆分带引号字段内部的逗号 const splitItems = item[0].split(/,(?=(?:[^"]*"[^"]*")*[^"]*$)/).map(str => str.trim()); const museumName = splitItems[0]; if (!map.has(museumName)) { map.set(museumName, []); } map.get(museumName).push(splitItems); return map; }, new Map()); // 2. 提取iArr中允许的博物馆名称集合 const allowedMuseums = new Set(iArr.map(row => row[0])); // 3. 遍历lArr进行替换 const out = lArr.map(lRow => { const museumName = lRow[0]; // 判断是否为允许替换的博物馆,且还有可用替换条目 if (allowedMuseums.has(museumName) && replacementMap.get(museumName)?.length > 0) { // 取出第一个可用条目并移除(确保下一次取新的) return replacementMap.get(museumName).shift(); } // 不符合条件则返回NONE数组 return ['NONE','NONE','NONE','NONE', 'NONE']; }); console.log(out);
代码关键点说明
- 智能拆分字符串:使用正则
split(/,(?=(?:[^"]*"[^"]*")*[^"]*$)/)拆分字符串,避免拆分带引号字段内部的逗号(比如"MAREIKE"里的特殊符号)。 - 分组存储替换条目:用
Map按博物馆名称存储所有可用的替换条目,实现快速查找。 - 逐个取用条目:使用
shift()取出对应馆的第一个条目并移除,确保重复的博物馆行会依次取用不同的替换条目。 - 快速权限判断:用
Set存储iArr中的博物馆名称,O(1)时间复杂度判断当前行是否允许替换。
内容的提问来源于stack exchange,提问作者emilianoSala
相关产品推荐
相关产品推荐

