1

I've been using a nuget package called ICal.net to load ics files to check for events that have recently been added.

I've noticed while using the IEnumerable Except method for this that some events are missed even though you can see that more events have been added.

I came across the Uid property in the Event, checked it out and noticed that its unique - https://github.com/rianjs/ical.net/blob/5176d27ac243eb98a01157f2ed7ff3e2852b98eb/v2/ical.NET/Interfaces/Components/IUniqueComponent.cs#L14

I wrote a IEqualityComparer<IEvent> for this using the Uid but now all events are being seen as new events.

Was just wondering if anyone had any suggestions on how I can take 2 calendars, compare the events and get the differences? Currently there is 2000+ events and increasing so trying to keep it performant.

4

2 回答 2

0

如果我理解正确,您有两个日历集合。一个代表具有多个 VEVENT 的 VCALENDAR,第二个代表稍后某个时间点的相同 VCALENDAR + VEVENT。出于显而易见的原因,通常后期的 VCALENDAR 比早期的日历有更多的事件。并且您想比较两者以查看差异,即找到新事件。

  • 使用Uid可能就足够了,也可能不够;这取决于您的日历系统。虽然每个 UID 应该是唯一的,但这取决于您的应用程序来保证。当 ical.net 创建事件时,它会执行 a Guid.NewGuid().ToString(),因此如果您使用 ical.net 创建事件,它们应该是唯一的。Google 日历和(我假设)其他流行的日历应用程序也提供了确定性唯一的 Uid。
  • ical.net 不考虑Uid用于相等或散列的重要性。相反,它关注事件本身的组成。

如果您知道每个事件的 UID 是唯一的,并且您没有兴趣将两个事件与不匹配的 Uid 进行比较,我会这样做:

var eventIdSet = new HashSet<string>(StringComparison.OrdinalIgnoreCase);
var firstEventIds = firstCalendarCollection
    .SelectMany(cc => cc.Event)
    .Select(e => e.Uid);
eventIdSet.UnionWith(firstEventIds);

var secondEventIds = secondCalendarCollection
    .SelectMany(cc => cc.Event)
    .Select(e => e.Uid);

eventIdSet.ExceptWith(secondEventIds);

这应该为您提供第一个集合中存在的新日历 ID,而不是第二个集合。

如果您想比较事件内容,我会遵循相同的模式,在Event对象处停止:

var firstSet = new HashSet<Event>();
var firstEvents = firstCalendarCollection.SelectMany(cc => cc.Event);
firstSet.UnionWith(firstEventIds);

var secondEvents = secondCalendarCollection.SelectMany(cc => cc.Event);
firstSet.ExceptWith(secondEvents);

这将做同样的事情,但正如我上面所说,事件 ID 被内部GetHashCodeEquals实现忽略。

单独比较Uids 比比较每个 s 的全部内容要快Event。也就是说,除非这是一个繁忙的服务器应用程序,必须每秒多次执行此操作,否则这无关紧要。我们正在使用 ical.net,并使用 800-1000 个日历事件进行这样的设置操作,它是 WPF 应用程序中计算时间的毫秒数。除非在极端情况下,否则您可能不会注意到Uid比较和整个内容比较之间的差异。Event

编辑:我创建了一个 wiki 页面:https ://github.com/rianjs/ical.net/wiki/Comparing-collections-of-calendar-events

于 2017-06-08T19:07:01.870 回答
0

我建议使用 LINQ 进行 Where In 查询。

假设您有两个集合(已注册且可能是新集合):

List<string> registeredIds = GetRegisteredComponentsUIds();

List<ComponentImplemenation> newEvents = GetNewEvents();

List<ComponentImplemenation> result = newEvents.Where(m => registeredIds.Contains(m.Uid))
                                               .ToList();
于 2017-06-07T06:43:49.753 回答