My reasoning is that you need a function that makes:
{ "EmailField" : "FirstName", "CrmField" : "FirstName" }
and
{ "EmailField" : "FirstName", "CrmField" : null }
the same value so a uniq operation will pick only one of them, however depending on which one comes first you can end up with either one of them. In terms of uniq the only other way around is differentiate them and in this case you end up with both which you don't want.
I suggest you use a filter operation that will remove the null values after the uniq.
A possible solution, though probably not the best one due to the extensive use of functions is:
var arr1 =
[
{ "EmailField" : "FirstName", "CrmField" : null },
{ "EmailField" : "LastName", "CrmField" : "LastName" },
{ "EmailField" : "Job", "CrmField" : "JobTitle" }
];
var arr2 =
[
{ "EmailField" : "FirstName", "CrmField" : "FirstName" },
{ "EmailField" : "LastName", "CrmField" : "LastName" },
{ "EmailField" : "Job", "CrmField" : "JobTitle" },
];
var res = _.flatten(_.map(_.groupBy(_.union(arr1, arr2), function (item) {
return item.EmailField;
}), function (set) {
if (set.length > 1) {
return _.filter(_.uniq(set, function (item) {
return item.EmailField + ' ' + item.CrmField;
}), function (item) {
return item.CrmField != null;
});
}
return set;
}));
console.log(res);
The uniq operation is replaced by a groupBy, then we use map and filter to weed out the null values this time taking into account how many instances of this EmailField we have - if there is only one we keep it. Finally we use a flatten to have again a single array of objects.