如何通过stopId匹配两个JavaScript数组并合并对象?
通过stopId合并两个数组对象的实现方案
核心思路
你要实现的是基于stopId关联两个数组中的对象,includes方法并不适合这个场景——它只能判断某个值是否直接存在于数组中,而你需要检查数组内对象的stopId属性是否匹配。正确的做法是用find(获取匹配对象)或some(仅判断是否存在)来做ID匹配,再合并对象。
基础实现(以info为主,匹配times中的对应项)
假设你的数组结构如下:
const info = [ { stopId: '1', name: 'Central Station', address: 'Main St 1' }, { stopId: '2', name: 'West Gate', address: 'West Rd 5' } ]; const times = [ { stopId: '1', arrival: '08:00', departure: '08:05' }, { stopId: '3', arrival: '09:10', departure: '09:15' } ];
遍历info数组,找到times中stopId相同的对象并合并:
const merged = info.map(infoItem => { // 找到对应stopId的times对象 const matchedTime = times.find(timeItem => timeItem.stopId === infoItem.stopId); // 合并对象,无匹配则保留原info项 return matchedTime ? { ...infoItem, ...matchedTime } : infoItem; }); console.log(merged); // 输出: // [ // { stopId: '1', name: 'Central Station', address: 'Main St 1', arrival: '08:00', departure: '08:05' }, // { stopId: '2', name: 'West Gate', address: 'West Rd 5' } // ]
双向匹配(保留所有stopId对应的合并项)
如果需要同时保留info和times中所有出现过的stopId,可以先收集所有ID再遍历:
// 收集所有唯一的stopId const allStopIds = new Set([ ...info.map(item => item.stopId), ...times.map(item => item.stopId) ]); const mergedAll = Array.from(allStopIds).map(stopId => { const infoItem = info.find(item => item.stopId === stopId) || {}; const timeItem = times.find(item => item.stopId === stopId) || {}; return { ...infoItem, ...timeItem }; }); console.log(mergedAll); // 输出包含stopId 1、2、3的合并对象
性能优化(大数据量场景)
如果数组元素较多,多次调用find会导致O(n²)的时间复杂度。可以先将其中一个数组转为Map,把查找复杂度降到O(1):
// 将times转为以stopId为键的Map const timesMap = new Map(times.map(item => [item.stopId, item])); const mergedFast = info.map(infoItem => { const matchedTime = timesMap.get(infoItem.stopId); return matchedTime ? { ...infoItem, ...matchedTime } : infoItem; });
为什么includes不适用
times.includes(infoItem.stopId)会检查数组中是否有直接等于infoItem.stopId的字符串,但times数组的元素是对象,不是字符串,因此永远返回false。你需要的是判断数组中是否存在对象的stopId属性等于目标值,这时候find或some才是正确选择。
内容的提问来源于stack exchange,提问作者lecham
相关产品推荐
相关产品推荐

