I have two arrays list1
and list2
which have objects with some properties; userId
is the Id or unique property:
list1 = [
{ userId: 1234, userName: 'XYZ' },
{ userId: 1235, userName: 'ABC' },
{ userId: 1236, userName: 'IJKL' },
{ userId: 1237, userName: 'WXYZ' },
{ userId: 1238, userName: 'LMNO' }
]
list2 = [
{ userId: 1235, userName: 'ABC' },
{ userId: 1236, userName: 'IJKL' },
{ userId: 1252, userName: 'AAAA' }
]
I'm looking for an easy way to execute the following three operations:
list1 operation list2
should return the intersection of elements:[ { userId: 1235, userName: 'ABC' }, { userId: 1236, userName: 'IJKL' } ]
list1 operation list2
should return the list of all elements fromlist1
which don't occur inlist2
:[ { userId: 1234, userName: 'XYZ' }, { userId: 1237, userName: 'WXYZ' }, { userId: 1238, userName: 'LMNO' } ]
list2 operation list1
should return the list of elements fromlist2
which don't occur inlist1
:[ { userId: 1252, userName: 'AAAA' } ]
Here is a functionnal programming solution with underscore/lodash to answer your first question (intersection).
I'll let you improve this to answer the other questions ;-)
This is the solution that worked for me.
You could define three functions
inBoth
,inFirstOnly
, andinSecondOnly
which all take two lists as arguments, and return a list as can be understood from the function name. The main logic could be put in a common functionoperation
that all three rely on.Here are a few implementations for that
operation
to choose from, for which you can find a snippet further down:for
loopsfilter
andsome
array methodsSet
Plain old
for
loopsArrow functions using
filter
andsome
array methodsThis uses some ES5 and ES6 features:
Optimising lookup
The above solutions have a O(n²) time complexity because of the nested loop --
some
represents a loop as well. So for large arrays you'd better create a (temporary) hash on user-id. This can be done on-the-fly by providing aSet
(ES6) as argument to a function that will generate the filter callback function. That function can then perform the look-up in constant time withhas
:Use lodash's
_.isEqual
method. Specifically:Above gives you the equivalent of
A given !B
(in SQL terms,A LEFT OUTER JOIN B
). You can move the code around the code to get what you want!