The need to create intersections, differences, and unions, comes up when we need to know values in common, exclusive, or unique to two or more data sets. For this month, create three functions:
- intersection(aList, bList) – Returns a list of values contained in both aList and bList.
- difference(aList, bList) – Returns two lists. The first contains the values in aList that are not in bList, the second contains the values in bList that are not in aList.
- union(aList, bList) – Returns a list of all values in aList and bList, removing any duplicates.
For example, if:
aList = {“a”,”b”,”c”,”d”,”e”,”e”}
bList = {“a”,”a”,”c”,”f”,”g”}
then,
intersection(aList,bList) => {“a”,”c”}
difference(aList,bList) => {{“b”,”d”,”e”},{“f”,”g”}}
union(aList,bList) => {“a”,”b”,”c”,”d”,”e”,”f”,”g”}
For extra credit, extend intersection and union to take a list of three or more lists.
Using associative arrays and recursion. The code might not be easiest to understand because I'm not: using clearly named supporting variables, using recursion and associative arrays, also missing all comments.
Names Default To Here(1);
intersection = function({temp_list}, {Default Local},
Try(
tempAa = Associative Array(temp_list[1]);
tempAa << Intersect(AssociativeArray(temp_list[2])),
return("not enough lists provided");
);
If(N Items(temp_list) == 2,
return(tempAa << get keys);
);
If(N Items(temp_list) > 2,
recurse(Insert(EvalList({tempAa << get keys}), Remove(temp_list, 1,2)))
);
);
difference = function({firstList, secondList}, {Default Local},
tempAaFirst = Associative Array(firstList);
tempAaSecond = Associative Array(secondList);
tempAaFirst << Remove(Associative Array(secondList));
tempAaSecond << Remove(Associative Array(firstList));
return(Eval List({tempAaFirst << get keys, tempAaSecond << get keys}));
);
union = function({temp_list}, {Default Local},
Try(
Insert Into(temp_list[1], temp_list[2]),
return("not enough lists provided");
);
If(N Items(temp_list) == 2,
return(Associative Array(temp_list[1]) << get keys);
);
If(N Items(temp_list) > 2,
recurse(Insert(EvalList({Associative Array(temp_list[1]) << get keys}), Remove(temp_list, 1,2)))
);
);
//test cases
Clear log();
aList = {"a","b","c","d","e","e"};
bList = {"a","a","c","f","g"};
cList = {"a", "b", "c", "h"};
dList = {"i", "j", "k"};
Print("intersection()");
Show(intersection(Eval List({aList})));
Show(intersection(Eval List({aList, bList})));
Show(intersection(Eval List({aList, bList, cList})));
Show(intersection(Eval List({aList, bList, cList, dList})));
Print("\!Ndifference()");
Show(difference(aList, bList));
Print("\!Nunion()");
Show(union(Eval List({aList})));
Show(union(Eval List({aList, bList})));
Show(union(Eval List({aList, bList, cList})));
Show(union(Eval List({aList, bList, cList, dList})));Might get a bit slow at least at removing duplicated values when using associative arrays, at least when getting unique values from datatables using Summarize gets faster at some point.