如何用JavaScript的map/reduce/filter筛选多供应商符合条件的可用客房?
解决方案:用map/reduce/filter筛选多供应商共有可用客房
步骤拆解
- 先筛选出符合物业名称匹配且日期区间覆盖用户入住退房日期的供应商数据
- 提取这些供应商的可用客房列表
- 通过
reduce统计每个客房的出现频次,找出所有供应商共有的客房(频次等于合格供应商数量)
示例JSON数据
const supplierData = [ { supplierId: 'sup1', propertyName: '海景酒店', availableFrom: '2024-05-01', availableTo: '2024-06-01', rooms: [ { roomId: 'room1', type: '标准间', price: 200 }, { roomId: 'room2', type: '大床房', price: 300 } ] }, { supplierId: 'sup2', propertyName: '海景酒店', availableFrom: '2024-04-25', availableTo: '2024-06-10', rooms: [ { roomId: 'room1', type: '标准间', price: 210 }, { roomId: 'room3', type: '套房', price: 500 } ] }, { supplierId: 'sup3', propertyName: '海景酒店', availableFrom: '2024-05-02', availableTo: '2024-05-30', rooms: [ { roomId: 'room1', type: '标准间', price: 190 } ] } ];
完整实现代码
// 用户输入参数 const userInput = { checkIn: '2024-05-05', checkOut: '2024-05-20', propertyName: '海景酒店' }; // 第一步:筛选合格的供应商 const qualifiedSuppliers = supplierData.filter(supplier => { // 物业名称匹配 const isPropertyMatch = supplier.propertyName === userInput.propertyName; // 日期区间覆盖:供应商的availableFrom <= checkIn,availableTo >= checkOut const isDateCovered = new Date(supplier.availableFrom) <= new Date(userInput.checkIn) && new Date(supplier.availableTo) >= new Date(userInput.checkOut); return isPropertyMatch && isDateCovered; }); // 第二步:提取所有合格供应商的客房列表 const allRooms = qualifiedSuppliers.flatMap(supplier => supplier.rooms); // 第三步:用reduce统计每个roomId的出现次数,找出共有客房 const commonRooms = Object.values( allRooms.reduce((acc, room) => { // 按roomId分组,统计出现次数,同时保留客房信息 if (!acc[room.roomId]) { acc[room.roomId] = { ...room, count: 0 }; } acc[room.roomId].count += 1; return acc; }, {}) ) // 筛选出现次数等于合格供应商数量的客房(即所有供应商都有) .filter(room => room.count === qualifiedSuppliers.length); console.log(commonRooms); // 输出:[{ roomId: 'room1', type: '标准间', price: 200, count: 3 }]
reduce核心逻辑解释
这里的reduce主要做按客房ID分组统计:
- 初始化空对象
acc作为累加器 - 遍历每间客房时,检查累加器中是否已有该
roomId的记录:- 无记录则创建新条目,复制客房信息并初始化
count为0 - 有记录则将
count加1
- 无记录则创建新条目,复制客房信息并初始化
- 最后把累加器的对象值转为数组,过滤出
count等于合格供应商数量的客房,这些就是所有供应商共有的可用客房
可选优化(合并客房信息)
如果需要合并不同供应商的客房数据(比如取最低价格),可以调整reduce逻辑:
allRooms.reduce((acc, room) => { if (!acc[room.roomId]) { acc[room.roomId] = { ...room, count: 1 }; } else { // 保留最低价格 acc[room.roomId].price = Math.min(acc[room.roomId].price, room.price); acc[room.roomId].count += 1; } return acc; }, {})
内容的提问来源于stack exchange,提问作者imc
相关产品推荐
相关产品推荐

