fix Set Difference and Set Intersection preserve duplicates from first sample
Deduplicate results in both operations to match mathematical set semantics, consistent with Set Union which already deduplicates. Closes #2241
This commit is contained in:
parent
b0fa1f8d1b
commit
4e1464b1e1
@ -75,9 +75,16 @@ class SetDifference extends Operation {
|
|||||||
* @returns {Object[]}
|
* @returns {Object[]}
|
||||||
*/
|
*/
|
||||||
runSetDifference(a, b) {
|
runSetDifference(a, b) {
|
||||||
|
const excluded = new Set(b);
|
||||||
|
const seen = new Set();
|
||||||
|
|
||||||
return a
|
return a
|
||||||
.filter((item) => {
|
.filter((item) => {
|
||||||
return b.indexOf(item) === -1;
|
if (excluded.has(item) || seen.has(item)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
seen.add(item);
|
||||||
|
return true;
|
||||||
})
|
})
|
||||||
.join(this.itemDelimiter);
|
.join(this.itemDelimiter);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,9 +75,16 @@ class SetIntersection extends Operation {
|
|||||||
* @returns {Object[]}
|
* @returns {Object[]}
|
||||||
*/
|
*/
|
||||||
runIntersect(a, b) {
|
runIntersect(a, b) {
|
||||||
|
const included = new Set(b);
|
||||||
|
const seen = new Set();
|
||||||
|
|
||||||
return a
|
return a
|
||||||
.filter((item) => {
|
.filter((item) => {
|
||||||
return b.indexOf(item) > -1;
|
if (!included.has(item) || seen.has(item)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
seen.add(item);
|
||||||
|
return true;
|
||||||
})
|
})
|
||||||
.join(this.itemDelimiter);
|
.join(this.itemDelimiter);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,4 +53,26 @@ TestRegister.addTests([
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Set Difference: duplicates in first set are removed",
|
||||||
|
input: "red,red,blue\n\nblue",
|
||||||
|
expectedOutput: "red",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Set Difference",
|
||||||
|
args: ["\n\n", ","],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Set Difference: duplicates in both sets",
|
||||||
|
input: "1 1 2 2 3\n\n2 2 3 3",
|
||||||
|
expectedOutput: "1",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Set Difference",
|
||||||
|
args: ["\n\n", " "],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|||||||
@ -52,5 +52,27 @@ TestRegister.addTests([
|
|||||||
args: ["z", "-"],
|
args: ["z", "-"],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
name: "Set Intersection: duplicates in first set are removed",
|
||||||
|
input: "red,red,blue\n\nred,blue",
|
||||||
|
expectedOutput: "red,blue",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Set Intersection",
|
||||||
|
args: ["\n\n", ","],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Set Intersection: duplicates in both sets",
|
||||||
|
input: "1 1 2 2 3\n\n2 2 3 3 4",
|
||||||
|
expectedOutput: "2 3",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Set Intersection",
|
||||||
|
args: ["\n\n", " "],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user