Skip to content

Commit ad37d36

Browse files
authored
fix(data-structures/unstable): BidirectionalMap differentiate extant undefined from missing values (#6606)
1 parent 40d05ea commit ad37d36

File tree

2 files changed

+67
-10
lines changed

2 files changed

+67
-10
lines changed

data_structures/unstable_bidirectional_map.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,11 @@ export class BidirectionalMap<K, V> extends Map<K, V> {
9595
* ```
9696
*/
9797
override set(key: K, value: V): this {
98-
const oldValue = super.get(key);
99-
if (oldValue !== undefined) {
100-
this.#reverseMap.delete(oldValue);
98+
if (super.has(key)) {
99+
this.#reverseMap.delete(super.get(key)!);
101100
}
102-
const oldKey = this.#reverseMap.get(value);
103-
if (oldKey !== undefined) {
104-
super.delete(oldKey);
101+
if (this.#reverseMap.has(value)) {
102+
super.delete(this.#reverseMap.get(value)!);
105103
}
106104
super.set(key, value);
107105
this.#reverseMap.set(value, key);
@@ -151,8 +149,8 @@ export class BidirectionalMap<K, V> extends Map<K, V> {
151149
* ```
152150
*/
153151
override delete(key: K): boolean {
154-
const value = super.get(key);
155-
if (value === undefined) return false;
152+
if (!super.has(key)) return false;
153+
const value = super.get(key)!;
156154
return super.delete(key) && this.#reverseMap.delete(value);
157155
}
158156

@@ -179,8 +177,8 @@ export class BidirectionalMap<K, V> extends Map<K, V> {
179177
* ```
180178
*/
181179
deleteReverse(value: V): boolean {
182-
const key = this.#reverseMap.get(value);
183-
if (key === undefined) return false;
180+
if (!this.#reverseMap.has(value)) return false;
181+
const key = this.#reverseMap.get(value)!;
184182
return super.delete(key) && this.#reverseMap.delete(value);
185183
}
186184

data_structures/unstable_bidirectional_map_test.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,3 +323,62 @@ Deno.test(
323323
assertEquals(bidiFromArr, bidiFromIter);
324324
},
325325
);
326+
327+
Deno.test(
328+
"BidirectionalMap differentiates extant `undefined` from missing values, consistently with `Map`",
329+
async (t) => {
330+
let bidi: BidirectionalMap<number | undefined, number | undefined>;
331+
332+
await t.step("delete", () => {
333+
bidi = new BidirectionalMap([[0, undefined]]);
334+
assertEquals(bidi.delete(0), true);
335+
assertEquals(bidi.delete(0), false);
336+
assertEquals(bidi.delete(1), false);
337+
});
338+
339+
await t.step("deleteReverse", () => {
340+
bidi = new BidirectionalMap([[undefined, 0]]);
341+
assertEquals(bidi.deleteReverse(0), true);
342+
assertEquals(bidi.deleteReverse(0), false);
343+
assertEquals(bidi.deleteReverse(1), false);
344+
});
345+
346+
await t.step("has", () => {
347+
bidi = new BidirectionalMap([[undefined, undefined]]);
348+
assertEquals(bidi.has(undefined), true);
349+
bidi.set(1, undefined);
350+
// gets removed due to `undefined` value (reverse key) being overwritten
351+
assertEquals(bidi.has(undefined), false);
352+
});
353+
354+
await t.step("hasReverse", () => {
355+
bidi = new BidirectionalMap([[undefined, undefined]]);
356+
assertEquals(bidi.hasReverse(undefined), true);
357+
bidi.set(undefined, 1);
358+
// gets removed due to `undefined` key being overwritten
359+
assertEquals(bidi.hasReverse(undefined), false);
360+
});
361+
362+
await t.step("set", () => {
363+
bidi = new BidirectionalMap([[undefined, undefined]]);
364+
bidi.set(undefined, 1);
365+
assertEquals([...bidi], [[undefined, 1]]);
366+
367+
bidi = new BidirectionalMap([[undefined, undefined]]);
368+
bidi.set(1, undefined);
369+
assertEquals([...bidi], [[1, undefined]]);
370+
371+
bidi = new BidirectionalMap([]);
372+
bidi.set(undefined, undefined);
373+
assertEquals([...bidi], [[undefined, undefined]]);
374+
375+
bidi = new BidirectionalMap([]);
376+
bidi.set(undefined, 1);
377+
assertEquals([...bidi], [[undefined, 1]]);
378+
379+
bidi = new BidirectionalMap([]);
380+
bidi.set(1, undefined);
381+
assertEquals([...bidi], [[1, undefined]]);
382+
});
383+
},
384+
);

0 commit comments

Comments
 (0)