Open endeavor85 opened 10 years ago
The straightforward approach involves, for each criterion, unioning items of selected values of all other criteria, then for each value of this criterion, determining how many items in the resulting set match that value. So letting C be the set of criteria, N = |C|, Vc the set of values in c (where c is a criterion in C), for each c in C we must perform up to |Vc| - 1 unions with items for each selected value in c to find c', the set of items matching active values of criterion c without regard for other criteria. Then for each c in C, we must perform N - 2 unions (with all other criteria in C), which is N * (N-2) unions for N > 1.
If we rephrase the requirement for each value's count to "the number of items there would be if we ignored this value's criterion and only considered the other criteria," we arrive at an alternative approach based on the premise that we are only concerned with items that only satisfy a single criterion (because if it satisfies multiple criteria it will never be absent from the result if we only ever discount a single criterion). We still perform up to (N * (|Vc| - 1)) unions to determine c' for each c in C. But now, rather than performing N * N - 2 more unions among criteria, we start adding all of the matching elements to a set s
. As we add, if an item is already in s
, it obviously matches multiple criteria so we can ignore it (don't add it to the set). The resulting set s
will only contain items matching a single criterion (though perhaps multiple values within that criterion). Now for each criterion c, subtract s
from c' to get c'', the set of items that remain regardless of this criterion. For each value of c, count the number of items in c'' with that value.
The value counts (#) for a criterion should display the number of items that satisfy the values selected in all other criteria. I.e, the value counts for a criterion should reflect the filtering of all other criteria, but not itself.