I have a situation where I have two arrays and I need to partition them so that I end up with 3 arrays:
- elements that are only in A
- elements that are only in B
- elements that are in both A and B
Example:
A = [1, 4, 3, 2]
B = [2, 6, 5, 3]
3part(A,B) => [[1,4], [6,5], [2,3]] # the order of the elements in each array doesn't matter
I've come up with a correct solution, but wonder if it could be quicker. It is (in pseudocode):
3part(A,B) =>
a_only = []
b_only = []
intersect = []
foreach a in A
if B.contains(a)
intersect.push(a)
else
a_only.push(a)
foreach b in B
if not intersect.contains(b)
b_only.push(b)
return [a_only, b_only, intersect]
In my case at hand, A & B will each contain up to 5000 complex structures (instead of ints) and it runs in about 1.5 secs. It gets used as part of a user interaction which can happen frequently, so ideally it would take < .5sec .
BTW, is there a name for this operation as a whole, other than "difference-difference-intersection"?
Thanks!
EDIT:
Based on the suggestions to use a hash, my updated code runs in under 40ms :-D
Here is the pseudocode:
(say that "key" is the element that I am using for comparison)
array_to_hash(A, Key)
h = {}
foreach a in A
h[a[Key]] = a
return h
3part(A,B) =>
a_only = []
b_only = []
intersect = {} // note this is now a hash instead of array
Ah = array_to_hash(A, 'key')
Bh = array_to_hash(B, 'key')
foreach ak in Ah.keys()
if Bh.hasKey(ak)
intersect[ak] = Ah[ak]
else
a_only.push(Ah[ak])
foreach bk in Bh.keys()
if not intersect.hasKey(bk)
b_only.push(Bh[bk])
return [a_only, b_only, intersect.values]
Thank you all for the suggestions.