在JavaScript中对比数组与嵌套数组并按索引生成新数组
问题分析
你有两个数组,需要根据arrayOne中的id匹配arrayTwo元素data数组里的id,生成符合预期的新数组。你给出的预期结果是[null, 'Bravo', null, 'Delta'],对应arrayTwo的4个元素,其中仅arrayTwo里data.id为202的元素保留了value,其余为null。
你之前的代码存在多处逻辑错误:
- 第一段代码中,
arrayOne的元素只有id属性,没有data,item.data.map(...)会直接报错;同时arrayTwo的元素没有直接的id属性,应该取itemTwo.data[0].id做匹配。 - 第二段代码中,
arrayTwo.filter()返回的是数组,在if判断里会被视为true,导致条件永远成立;另外arrayTwo.data是错误的访问方式,arrayTwo是数组,应该访问单个元素的data属性。
正确实现
根据你的预期结果,这里提供两种匹配逻辑的实现:
仅匹配arrayOne中指定索引的id(完全符合你的预期结果)
如果需求是只匹配arrayOne索引为1的id(即202),可以这样写:
const targetId = arrayOne[1]?.id; const newArray = arrayTwo.map(twoItem => { const dataItem = twoItem.data[0]; return dataItem.id === targetId ? dataItem.value : null; });
执行后结果:[null, 'Bravo', null, 'Delta']
匹配arrayOne中所有id(通用场景)
如果是要匹配arrayOne中所有存在的id,则:
// 先提取arrayOne的所有id,用Set提升匹配效率 const oneIds = new Set(arrayOne.map(item => item.id)); const newArray = arrayTwo.map(twoItem => { const dataItem = twoItem.data[0]; return oneIds.has(dataItem.id) ? dataItem.value : null; });
执行后结果:[null, 'Bravo', 'Charlie', 'Delta']
按索引一一对应匹配(若arrayTwo与arrayOne长度一致)
如果需求是arrayTwo和arrayOne按索引对应,对比相同索引下的id,则:
const newArray = arrayTwo.map((twoItem, idx) => { const oneItem = arrayOne[idx]; if (!oneItem) return null; const dataItem = twoItem.data[0]; return dataItem.id === oneItem.id ? dataItem.value : null; });
执行后结果:[null, 'Bravo', null, null]
原代码问题详解
第一段代码:
item.data.map(...):arrayOne的元素仅包含id,没有data属性,会抛出Cannot read properties of undefined (reading 'map')错误。itemTwo.id:arrayTwo的元素是包含data的对象,没有直接的id属性,正确写法是itemTwo.data[0].id。
第二段代码:
arrayTwo.filter(...):filter返回数组,非空数组在if判断中会被转为true,导致条件永远成立。arrayTwo.data[idx].value:arrayTwo是数组,没有data属性,正确写法是itemTwo.data[0].value。
内容的提问来源于stack exchange,提问作者Aaron
相关产品推荐
相关产品推荐

