JavaScript对象数组拆分及时间表冲突检测方案咨询
Hey there! Let's work through your schedule planner challenges step by step—first getting that data structure sorted, then finding a smarter way to check for time conflicts than a Cartesian product.
First, let's tackle splitting each course's slots array into individual objects. Since your dataset is meant to be expandable, hardcoding separate variables like newArray, newArray2 isn't ideal—instead, we can use dynamic grouping to handle any number of courses.
Option 1: Get a single flattened array of all slot entries
If you want one big array with every course-slot pair (great for processing all slots at once), use flatMap:
const myCourses = [ // Your existing course data here ]; // Flatten into [{ course: "ee3001", slot: { day: "...", time: "..." } }, ...] const flattenedCourses = myCourses.flatMap(course => course.slots.map(slot => ({ course: course.course, slot: slot })) );
Option 2: Group entries by course code (for separate arrays)
If you still want separate arrays per course (but scalable), use reduce to build an object where keys are course codes:
const coursesByCode = myCourses.reduce((acc, course) => { // Convert each slot in the course to the target structure acc[course.course] = course.slots.map(slot => ({ course: course.course, slot: slot })); return acc; }, {}); // Access individual course arrays like this: const newArray = coursesByCode["ee3001"]; const newArray2 = coursesByCode["ee3002"]; // Any new courses you add will automatically appear in coursesByCode
Using a Cartesian product to check conflicts works for small datasets, but it gets slow fast as you add more courses (it’s O(n²) complexity). A better approach is to:
- Group all slots by day
- Sort each day's slots by start time
- Check adjacent slots for overlaps (since sorted slots only need to be compared to the previous one)
Here’s how to implement that:
// First, use the flattenedCourses array from earlier const slotsByDay = flattenedCourses.reduce((acc, item) => { const day = item.slot.day; if (!acc[day]) acc[day] = []; // Convert time strings to numbers for easy comparison (e.g., "0900" → 900) const [startStr, endStr] = item.slot.time.split('-'); acc[day].push({ course: item.course, start: parseInt(startStr, 10), end: parseInt(endStr, 10), originalSlot: item.slot }); return acc; }, {}); // Function to detect conflicts across all days function findTimeConflicts(slotsByDay) { const conflicts = []; for (const day in slotsByDay) { const daySlots = slotsByDay[day]; // Sort slots by their start time daySlots.sort((a, b) => a.start - b.start); // Check each slot against the previous one for overlap for (let i = 1; i < daySlots.length; i++) { const prev = daySlots[i-1]; const curr = daySlots[i]; // If current slot starts before the previous one ends → conflict! if (curr.start < prev.end) { conflicts.push({ day: day, conflictingCourses: [prev.course, curr.course], conflictingSlots: [prev.originalSlot, curr.originalSlot], overlapTime: `${Math.max(prev.start, curr.start)}-${Math.min(prev.end, curr.end)}` }); } } } return conflicts; } // Example usage const allConflicts = findTimeConflicts(slotsByDay); console.log(allConflicts);
Why this is better:
- Faster performance: Sorting each day’s slots is O(m log m) (m = number of slots that day), and checking overlaps is O(m). This is way more efficient than the Cartesian product’s O(n²) as your course list grows.
- Clearer results: You get specific details about which courses conflict, on which day, and exactly when the overlap happens.
内容的提问来源于stack exchange,提问作者Kwan Xhen

