You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Set method that returns all areas of a set intersection #184
However this is not very performant, as we are iterating each set multiple times. Thus a performant method could be implemented. The name fullIntersection is just a placeholder, I'm sure there is a better name for this.
As an added bonus we could even take this one step further and have a fullIntersectionBy variant. In most cases this would be much more useful:
Ran into this need again. Here are possible implementations and an improved version:
extension [T](existingItems: Set[T])
// A \ B, A ∩ B, and B \ AdefvennAreas(newItems: Set[T]): (Set[T], Set[T], Set[T]) =varremoved=Set.empty[T]
varunchanged=Set.empty[T]
varadded= newItems
for item <- existingItems doif added.contains(item) then
unchanged += item
added -= item
else removed += item
(removed, unchanged, added)
defvennAreasBy[K](newItems: Set[T])(f: T=>K): (Set[T], Set[(T, T)], Set[T]) =varremoved=Set.empty[T]
varmodified=Set.empty[(T, T)]
varaddedByKey= newItems.map(a => f(a) -> a).toMap
for item <- existingItems dovalkey= f(item)
addedByKey.get(key) matchcaseSome(newItem) =>
modified += (item -> newItem)
addedByKey -= key
caseNone=>
removed += item
(removed, modified, addedByKey.values.toSet)
extension [K, V](existingItems: Map[K, V])
/** Returns the venn areas of the existing and new items, where the key is used to determine the intersection. The * values are returned as follows: * - First element (A \ B): items present in existingItems but not in newItems * - Second element (A ∩ B): items present in both existingItems and newItems, with their values (old value, new * value) as a tuple * - Third element (B \ A): items present in newItems but not in existingItems*/defvennAreas(newItems: Map[K, V]): (Map[K, V], Map[K, (V, V)], Map[K, V]) =varremoved=Map.empty[K, V]
varmodified=Map.empty[K, (V, V)]
varadded= newItems
for (key, value) <- existingItems do
added.get(key) matchcaseSome(newValue) =>
modified += (key -> (value, newValue))
added -= key
caseNone=>
removed += (key -> value)
(removed, modified, added)
The implementation is reasonable, but can probably be improved.
This is a general solution to comparing two sets (or lists, or maps) of things. You get to know what is only in set1, what is in set1 and set2 (the intersection), and what is only in set2. This pattern is also helpful to compare a collection of things that gets changed over time and you want to figure out what was added, what was removed, and what stayed the same (according to some key, hence f). Its also useful to determine what will change if you apply some changes to the collection.
Let me give some concrete examples:
You have a list of applications deployed to the acceptance environment. Using these functions you can compare acceptance with production. Thus it will be easy to see which new applications will be deployed, which applications will be removed, and which applications just got a version upgrade the tuple (T, T) or (V, V) (for the map) will make it easy to figure out the old vs new version.
The base implementation is just a combination of diff+intersect. But the variant *By receiving f or the Map variant is where this pattern really shines.
Activity
simaomartins-visma commentedon Mar 30, 2026
Ran into this need again. Here are possible implementations and an improved version:
The implementation is reasonable, but can probably be improved.
bishabosha commentedon Jun 22, 2026
i would like to ask when this would be useful to general programmers rather than a toy example for drawing venn diagrams.
is it just for auditing purposes?
Lasering commentedon Jun 30, 2026
The name vennAreas is not the best.
This is a general solution to comparing two sets (or lists, or maps) of things. You get to know what is only in set1, what is in set1 and set2 (the intersection), and what is only in set2. This pattern is also helpful to compare a collection of things that gets changed over time and you want to figure out what was added, what was removed, and what stayed the same (according to some key, hence
f). Its also useful to determine what will change if you apply some changes to the collection.Let me give some concrete examples:
(T, T)or(V, V)(for the map) will make it easy to figure out the old vs new version.commcommand in linuxThe base implementation is just a combination of diff+intersect. But the variant
*Byreceivingfor the Map variant is where this pattern really shines.bishabosha commentedon Jun 30, 2026
the animation example does seem a great use case (show different things to user for "transition states")