按条件减少和分组

问题描述 投票:0回答:1

我有一个函数可以计算同时发生的最大事件数(HH:mm)。下面的示例同时发生三个事件。我想对事件进行分组,例如下面的示例。

结果应该是:

数字会议00:00-01.00

  • 第1组:支持00.00-00.25

  • 第2组:读书会00:30-01:30个人会议00:30-01:30

Four events, where three occurs at the same time

到目前为止,我只能找到一个事件的发生。我想我必须使用减速器和条件?

let events = [
  {
    id: 9,
    start: 0,
    end: 60,
    title: "Digital meeting"
  },
  {
    id: 80,
    start: 30,
    end: 90,
    title: "Book meeting"
  },
  {
    id: 81,
    start: 30,
    end: 90,
    title: "Personal meeting"
  },
  {
    id: 84,
    start: 0,
    end: 24,
    title: "Support"
  }]

 events.forEach(item => {

// Find the matches
const matchedItems = events.filter(o => {
  return o.start <= item.end && o.end >= item.start && item.id !== o.id;
});

console.log(`Matched for ${item.id}`, matchedItems)

// Remove matches from the events array so there won't be duplicates
//remove(matchedItems);

// Format the items and place them in calendar grid
//format([item, ...matchedItems]);
   });
javascript arrays css-grid reduce
1个回答
0
投票

我为您实现了一个功能,请参见下面的代码,欢迎您

// calculate if 2 events overlap, no matter of their provided order
function overlap(eventA, eventB) {

  // sort input
  const [first, second] = [eventA, eventB].sort((a, b) => a.start - b.start);
  
  // check if events overlap
  const overlap = first.end > second.start;
  return overlap;
}

// create a map object with the groups
// also sorted by time
// each group contains the event objects
function findOverlaps(events, query) {

  // result
  const groups = {};
  
  // event to build the groups for
  const queryEvent = events.find(e => e.title === query);
  
  // the other events to check of they overlap with the querried event
  const eventsWithoutQuery = events.filter(e => e.title !== query);
  eventsWithoutQuery.forEach(event => {
    const overlaps = overlap(event, queryEvent);
    
    // if there is an overlap
    if (overlaps) {
      // construct the groupname
      const groupName = `${event.start}-${event.end}`;

      // if the group alread exists use it, otherwise create an empty group (array)
      const group = groups[groupName] ? groups[groupName] : [];
      group.push(event);
      
      // put the group back to the groups map and name it accordingly
      groups[groupName] = group;
    }
  });
  
  // make sure the keys in the group are sorted (optional)
  const sortedKeys = Object.keys(groups).sort();
  const sortedGroups = sortedKeys.reduce(
    (acc, curr) => ({
      ...acc,
      [curr]: groups[curr]
    }),
    {}
  );
  
  // return sorted map
  return sortedGroups;
}


// the events
let events = [
    {
      id: 9,
      start: 0,
      end: 60,
      title: "Digital meeting"
    },
    {
      id: 80,
      start: 30,
      end: 90,
      title: "Book meeting"
    },
    {
      id: 81,
      start: 30,
      end: 90,
      title: "Personal meeting"
    },
    {
      id: 84,
      start: 0,
      end: 24,
      title: "Support"
    }
  ];
 

  console.log("Iterate over Digital meeting groups");
  // construct the groups for "Digial meeting" 
  const groups = findOverlaps(events, "Digital meeting");

  // iterate over overlap maps of Digital meeting
  for (const [groupName, eventsOfGroup] of Object.entries(groups)) {
  
    console.log(groupName, eventsOfGroup);
  }
  
  console.log("Iterate over everything");
  events.forEach(e => {   
    console.log("Groups for: " + e.title);
    for (const [groupName, eventsOfGroup] of Object.entries(findOverlaps(events, e.title))) {  
      console.log(groupName, eventsOfGroup);
    }  
  });
  
  
© www.soinside.com 2019 - 2024. All rights reserved.