Skip to content

Commit e766d1c

Browse files
authored
Support for new ecmascript Set methods (#1563)
1 parent e4afda0 commit e766d1c

File tree

2 files changed

+304
-0
lines changed

2 files changed

+304
-0
lines changed

src/lualib/Set.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,90 @@ export class Set<T extends AnyNotNil> {
145145
},
146146
};
147147
}
148+
149+
/**
150+
* @returns a new Set containing all the elements in this Set and also all the elements in the argument.
151+
*/
152+
public union(other: ReadonlySet<T>): Set<T> {
153+
const result = new Set<T>(this);
154+
for (const item of other) {
155+
result.add(item);
156+
}
157+
return result;
158+
}
159+
160+
/**
161+
* @returns a new Set containing all the elements which are both in this Set and in the argument.
162+
*/
163+
public intersection(other: ReadonlySet<T>) {
164+
const result = new Set<T>();
165+
for (const item of this) {
166+
if (other.has(item)) {
167+
result.add(item);
168+
}
169+
}
170+
return result;
171+
}
172+
173+
/**
174+
* @returns a new Set containing all the elements in this Set which are not also in the argument.
175+
*/
176+
public difference(other: ReadonlySet<T>): Set<T> {
177+
const result = new Set<T>(this);
178+
for (const item of other) {
179+
result.delete(item);
180+
}
181+
return result;
182+
}
183+
184+
/**
185+
* @returns a new Set containing all the elements which are in either this Set or in the argument, but not in both.
186+
*/
187+
public symmetricDifference(other: ReadonlySet<T>): Set<T> {
188+
const result = new Set<T>(this);
189+
for (const item of other) {
190+
if (this.has(item)) {
191+
result.delete(item);
192+
} else {
193+
result.add(item);
194+
}
195+
}
196+
return result;
197+
}
198+
199+
/**
200+
* @returns a boolean indicating whether all the elements in this Set are also in the argument.
201+
*/
202+
public isSubsetOf(other: ReadonlySet<unknown>): boolean {
203+
for (const item of this) {
204+
if (!other.has(item)) {
205+
return false;
206+
}
207+
}
208+
return true;
209+
}
210+
211+
/**
212+
* @returns a boolean indicating whether all the elements in the argument are also in this Set.
213+
*/
214+
public isSupersetOf(other: ReadonlySet<unknown>): boolean {
215+
for (const item of other) {
216+
if (!this.has(item as T)) {
217+
return false;
218+
}
219+
}
220+
return true;
221+
}
222+
223+
/**
224+
* @returns a boolean indicating whether this Set has no elements in common with the argument.
225+
*/
226+
public isDisjointFrom(other: ReadonlySetLike<unknown>): boolean {
227+
for (const item of this) {
228+
if (other.has(item)) {
229+
return false;
230+
}
231+
}
232+
return true;
233+
}
148234
}

test/unit/builtins/set.spec.ts

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,221 @@ test("instanceof Set without creating set", () => {
201201
return myset instanceof Set;
202202
`.expectToMatchJsResult();
203203
});
204+
205+
describe("new ECMAScript Set methods", () => {
206+
test("union", () => {
207+
util.testFunction`
208+
const set1 = new Set([1,2,3,4,5,6]);
209+
const set2 = new Set([4,5,6,7,8,9]);
210+
211+
const intersection = set1.union(set2);
212+
return [...intersection];
213+
`.expectToEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]);
214+
});
215+
216+
test("union with empty sets", () => {
217+
util.testFunction`
218+
const set1 = new Set([1,2,3,4,5,6]);
219+
const set2 = new Set([]);
220+
221+
const intersection = set1.union(set2);
222+
return [...intersection];
223+
`.expectToEqual([1, 2, 3, 4, 5, 6]);
224+
225+
util.testFunction`
226+
const set1 = new Set([]);
227+
const set2 = new Set([4,5,6,7,8,9]);
228+
229+
const intersection = set1.union(set2);
230+
return [...intersection];
231+
`.expectToEqual([4, 5, 6, 7, 8, 9]);
232+
});
233+
234+
test("intersection", () => {
235+
util.testFunction`
236+
const set1 = new Set([1,2,3,4,5,6]);
237+
const set2 = new Set([4,5,6,7,8,9]);
238+
239+
const intersection = set1.intersection(set2);
240+
return [...intersection];
241+
`.expectToEqual([4, 5, 6]);
242+
});
243+
244+
test("intersection with empty sets", () => {
245+
util.testFunction`
246+
const set1 = new Set([1,2,3,4,5,6]);
247+
const set2 = new Set([]);
248+
249+
const intersection = set1.intersection(set2);
250+
return [...intersection];
251+
`.expectToEqual([]);
252+
253+
util.testFunction`
254+
const set1 = new Set([]);
255+
const set2 = new Set([4,5,6,7,8,9]);
256+
257+
const intersection = set1.intersection(set2);
258+
return [...intersection];
259+
`.expectToEqual([]);
260+
});
261+
262+
test("difference", () => {
263+
util.testFunction`
264+
const set1 = new Set([1,2,3,4,5,6]);
265+
const set2 = new Set([4,5,6,7,8,9]);
266+
267+
const intersection = set1.difference(set2);
268+
return [...intersection];
269+
`.expectToEqual([1, 2, 3]);
270+
});
271+
272+
test("symmetricDifference", () => {
273+
util.testFunction`
274+
const set1 = new Set([1,2,3,4,5,6]);
275+
const set2 = new Set([4,5,6,7,8,9]);
276+
277+
const intersection = set1.symmetricDifference(set2);
278+
return [...intersection];
279+
`.expectToEqual([1, 2, 3, 7, 8, 9]);
280+
});
281+
282+
test("isSubsetOf", () => {
283+
util.testFunction`
284+
const set1 = new Set([3,4,5,6]);
285+
const set2 = new Set([1,2,3,4,5,6,7,8,9]);
286+
287+
return {
288+
set1SubsetOfSet2: set1.isSubsetOf(set2),
289+
set2SubsetOfSet1: set2.isSubsetOf(set1),
290+
};
291+
`.expectToEqual({
292+
set1SubsetOfSet2: true,
293+
set2SubsetOfSet1: false,
294+
});
295+
});
296+
297+
test("isSubsetOf equal", () => {
298+
util.testFunction`
299+
const set1 = new Set([1,2,3,4,5,6,7,8,9]);
300+
const set2 = new Set([1,2,3,4,5,6,7,8,9]);
301+
302+
return {
303+
set1SubsetOfSet2: set1.isSubsetOf(set2),
304+
set2SubsetOfSet1: set2.isSubsetOf(set1),
305+
};
306+
`.expectToEqual({
307+
set1SubsetOfSet2: true,
308+
set2SubsetOfSet1: true,
309+
});
310+
});
311+
312+
test("isSubsetOf empty", () => {
313+
util.testFunction`
314+
const set1 = new Set([]);
315+
const set2 = new Set([1,2,3]);
316+
317+
return {
318+
set1SubsetOfSet2: set1.isSubsetOf(set2),
319+
set2SubsetOfSet1: set2.isSubsetOf(set1),
320+
};
321+
`.expectToEqual({
322+
set1SubsetOfSet2: true,
323+
set2SubsetOfSet1: false,
324+
});
325+
});
326+
327+
test("isSupersetOf", () => {
328+
util.testFunction`
329+
const set1 = new Set([3,4,5,6]);
330+
const set2 = new Set([1,2,3,4,5,6,7,8,9]);
331+
332+
return {
333+
set1SupersetOfSet2: set1.isSupersetOf(set2),
334+
set2SupersetOfSet1: set2.isSupersetOf(set1),
335+
};
336+
`.expectToEqual({
337+
set1SupersetOfSet2: false,
338+
set2SupersetOfSet1: true,
339+
});
340+
});
341+
342+
test("isSupersetOf equal", () => {
343+
util.testFunction`
344+
const set1 = new Set([1,2,3,4,5,6,7,8,9]);
345+
const set2 = new Set([1,2,3,4,5,6,7,8,9]);
346+
347+
return {
348+
set1SupersetOfSet2: set1.isSupersetOf(set2),
349+
set2SupersetOfSet1: set2.isSupersetOf(set1),
350+
};
351+
`.expectToEqual({
352+
set1SupersetOfSet2: true,
353+
set2SupersetOfSet1: true,
354+
});
355+
});
356+
357+
test("isSupersetOf empty", () => {
358+
util.testFunction`
359+
const set1 = new Set([]);
360+
const set2 = new Set([1,2,3]);
361+
362+
return {
363+
set1SupersetOfSet2: set1.isSupersetOf(set2),
364+
set2SupersetOfSet1: set2.isSupersetOf(set1),
365+
};
366+
`.expectToEqual({
367+
set1SupersetOfSet2: false,
368+
set2SupersetOfSet1: true,
369+
});
370+
});
371+
372+
test("isDisjointFrom", () => {
373+
util.testFunction`
374+
const set1 = new Set([3,4,5,6]);
375+
const set2 = new Set([7,8,9]);
376+
const set3 = new Set([1,2,3,4]);
377+
378+
return {
379+
set1DisjointFromSet2: set1.isDisjointFrom(set2),
380+
set2DisjointFromSet1: set2.isDisjointFrom(set1),
381+
set1DisjointFromSet3: set1.isDisjointFrom(set3),
382+
set3DisjointFromSet1: set3.isDisjointFrom(set1),
383+
};
384+
`.expectToEqual({
385+
set1DisjointFromSet2: true,
386+
set2DisjointFromSet1: true,
387+
set1DisjointFromSet3: false,
388+
set3DisjointFromSet1: false,
389+
});
390+
});
391+
392+
test("isDisjointFrom equal", () => {
393+
util.testFunction`
394+
const set1 = new Set([1,2,3,4,5,6,7,8,9]);
395+
const set2 = new Set([1,2,3,4,5,6,7,8,9]);
396+
397+
return {
398+
set1DisjointFromSet2: set1.isDisjointFrom(set2),
399+
set2DisjointFromSet1: set2.isDisjointFrom(set1),
400+
};
401+
`.expectToEqual({
402+
set1DisjointFromSet2: false,
403+
set2DisjointFromSet1: false,
404+
});
405+
});
406+
407+
test("isDisjointFrom empty", () => {
408+
util.testFunction`
409+
const set1 = new Set([]);
410+
const set2 = new Set([1,2,3]);
411+
412+
return {
413+
set1DisjointFromSet2: set1.isDisjointFrom(set2),
414+
set2DisjointFromSet1: set2.isDisjointFrom(set1),
415+
};
416+
`.expectToEqual({
417+
set1DisjointFromSet2: true,
418+
set2DisjointFromSet1: true,
419+
});
420+
});
421+
});

0 commit comments

Comments
 (0)