Skip to content

Commit 3b8df63

Browse files
authoredNov 7, 2023
feat: align some methods with the Set Methods proposal (#8890)
feat(collection): align/add methods with/from Set Methods proposal BREAKING CHANGE: The `intersect` method has been renamed to `intersection` BREAKING CHANGE: The `difference` method has been renamed to `symmetricDifference` BREAKING CHANGE: The `subtract` method has been renamed to `difference`
1 parent 054eaec commit 3b8df63

File tree

2 files changed

+99
-39
lines changed

2 files changed

+99
-39
lines changed
 

‎packages/collection/__tests__/collection.test.ts

+33-23
Original file line numberDiff line numberDiff line change
@@ -116,16 +116,15 @@ describe('combineEntries() tests', () => {
116116
});
117117

118118
describe('difference() tests', () => {
119-
const coll1 = createCollectionFrom(['a', 1], ['b', 2]);
120-
const coll2 = createTestCollection();
121-
const diff = createCollectionFrom(['c', 3]);
119+
const coll1 = createCollectionFrom(['a', 1], ['b', 2], ['c', 3]);
120+
const coll2 = createCollectionFrom(['b', 2], ['d', 4], ['e', 5]);
122121

123-
test('it removes entries from the bigger collection on the right', () => {
124-
expect(coll1.difference(coll2)).toStrictEqual(diff);
122+
test('it returns the difference the collections', () => {
123+
expect(coll1.difference(coll2)).toStrictEqual(createCollectionFrom(['a', 1], ['c', 3]));
125124
});
126125

127-
test('removes the difference from the bigger collection on the left', () => {
128-
expect(coll2.difference(coll1)).toStrictEqual(diff);
126+
test('it returns the difference the collections from the opposite order', () => {
127+
expect(coll2.difference(coll1)).toStrictEqual(createCollectionFrom(['d', 4], ['e', 5]));
129128
});
130129
});
131130

@@ -407,12 +406,12 @@ describe('hasAny() tests', () => {
407406
});
408407
});
409408

410-
describe('intersect() tests', () => {
409+
describe('intersection() tests', () => {
411410
const coll1 = createCollectionFrom(['a', 1], ['b', 2]);
412411
const coll2 = createCollectionFrom(['a', 1], ['c', 3]);
413412

414-
test('it returns a new collection', () => {
415-
const c = coll1.intersect(coll2);
413+
test('it returns the intersection of the collections', () => {
414+
const c = coll1.intersection(coll2);
416415
expect(c).toBeInstanceOf(Collection);
417416
expect(c.size).toStrictEqual(1);
418417

@@ -776,19 +775,6 @@ describe('sort() tests', () => {
776775
});
777776
});
778777

779-
describe('subtract() tests', () => {
780-
const coll1 = createCollectionFrom(['a', 1], ['b', 2], ['c', 3], ['d', undefined]);
781-
const coll2 = createCollectionFrom(['b', 2], ['c', 0]);
782-
783-
test('it returns a new collection', () => {
784-
const c = coll1.subtract(coll2);
785-
expect(c).toBeInstanceOf(Collection);
786-
expect(c.size).toStrictEqual(3);
787-
788-
expect(c).toStrictEqual(createCollectionFrom(['a', 1], ['c', 3], ['d', undefined]));
789-
});
790-
});
791-
792778
describe('sweep() test', () => {
793779
const coll = createTestCollection();
794780

@@ -816,6 +802,17 @@ describe('sweep() test', () => {
816802
});
817803
});
818804

805+
describe('symmetricDifference() tests', () => {
806+
const coll1 = createCollectionFrom(['a', 1], ['b', 2], ['c', 3]);
807+
const coll2 = createCollectionFrom(['b', 2], ['d', 4], ['e', 5]);
808+
809+
test('it returns the symmetric difference of the collections', () => {
810+
expect(coll1.symmetricDifference(coll2)).toStrictEqual(
811+
createCollectionFrom(['a', 1], ['c', 3], ['d', 4], ['e', 5]),
812+
);
813+
});
814+
});
815+
819816
describe('tap() tests', () => {
820817
const coll = createTestCollection();
821818

@@ -845,6 +842,19 @@ describe('toJSON() tests', () => {
845842
});
846843
});
847844

845+
describe('union() tests', () => {
846+
const coll1 = createCollectionFrom(['a', 1], ['b', 2]);
847+
const coll2 = createCollectionFrom(['a', 1], ['c', 3]);
848+
849+
test('it returns the union of the collections', () => {
850+
const c = coll1.union(coll2);
851+
expect(c).toBeInstanceOf(Collection);
852+
expect(c.size).toStrictEqual(3);
853+
854+
expect(c).toStrictEqual(createCollectionFrom(['a', 1], ['b', 2], ['c', 3]));
855+
});
856+
});
857+
848858
describe('random thisArg tests', () => {
849859
const coll = createCollectionFrom(['a', 3], ['b', 2], ['c', 1]) as Collection<string, unknown>;
850860

‎packages/collection/src/collection.ts

+66-16
Original file line numberDiff line numberDiff line change
@@ -751,52 +751,102 @@ export class Collection<K, V> extends Map<K, V> {
751751
}
752752

753753
/**
754-
* The intersect method returns a new structure containing items where the keys and values are present in both original structures.
754+
* The intersection method returns a new collection containing the items where the key is present in both collections.
755755
*
756756
* @param other - The other Collection to filter against
757+
* @example
758+
* ```ts
759+
* const col1 = new Collection([['a', 1], ['b', 2]]);
760+
* const col2 = new Collection([['a', 1], ['c', 3]]);
761+
* const intersection = col1.intersection(col2);
762+
* console.log(col1.intersection(col2));
763+
* // => Collection { 'a' => 1 }
764+
* ```
757765
*/
758-
public intersect<T>(other: ReadonlyCollection<K, T>): Collection<K, T> {
759-
const coll = new this.constructor[Symbol.species]<K, T>();
766+
public intersection<T>(other: ReadonlyCollection<K, T>): Collection<K, T | V> {
767+
const coll = new this.constructor[Symbol.species]<K, T | V>();
768+
769+
for (const [key, value] of this) {
770+
if (other.has(key)) coll.set(key, value);
771+
}
772+
773+
return coll;
774+
}
775+
776+
/**
777+
* Returns a new collection containing the items where the key is present in either of the collections.
778+
*
779+
* @remarks
780+
*
781+
* If the collections have any items with the same key, the value from the first collection will be used.
782+
* @param other - The other Collection to filter against
783+
* @example
784+
* ```ts
785+
* const col1 = new Collection([['a', 1], ['b', 2]]);
786+
* const col2 = new Collection([['a', 1], ['b', 3], ['c', 3]]);
787+
* const union = col1.union(col2);
788+
* console.log(union);
789+
* // => Collection { 'a' => 1, 'b' => 2, 'c' => 3 }
790+
* ```
791+
*/
792+
public union<T>(other: ReadonlyCollection<K, T>): Collection<K, T | V> {
793+
const coll = new this.constructor[Symbol.species]<K, T | V>(this);
794+
760795
for (const [key, value] of other) {
761-
if (this.has(key) && Object.is(value, this.get(key))) {
762-
coll.set(key, value);
763-
}
796+
if (!coll.has(key)) coll.set(key, value);
764797
}
765798

766799
return coll;
767800
}
768801

769802
/**
770-
* The subtract method returns a new structure containing items where the keys and values of the original structure are not present in the other.
803+
* Returns a new collection containing the items where the key is present in this collection but not the other.
771804
*
772805
* @param other - The other Collection to filter against
806+
* @example
807+
* ```ts
808+
* const col1 = new Collection([['a', 1], ['b', 2]]);
809+
* const col2 = new Collection([['a', 1], ['c', 3]]);
810+
* console.log(col1.difference(col2));
811+
* // => Collection { 'b' => 2 }
812+
* console.log(col2.difference(col1));
813+
* // => Collection { 'c' => 3 }
814+
* ```
773815
*/
774-
public subtract<T>(other: ReadonlyCollection<K, T>): Collection<K, V> {
816+
public difference<T>(other: ReadonlyCollection<K, T>): Collection<K, V> {
775817
const coll = new this.constructor[Symbol.species]<K, V>();
818+
776819
for (const [key, value] of this) {
777-
if (!other.has(key) || !Object.is(value, other.get(key))) {
778-
coll.set(key, value);
779-
}
820+
if (!other.has(key)) coll.set(key, value);
780821
}
781822

782823
return coll;
783824
}
784825

785826
/**
786-
* The difference method returns a new structure containing items where the key is present in one of the original structures but not the other.
827+
* Returns a new collection containing only the items where the keys are present in either collection, but not both.
787828
*
788829
* @param other - The other Collection to filter against
830+
* @example
831+
* ```ts
832+
* const col1 = new Collection([['a', 1], ['b', 2]]);
833+
* const col2 = new Collection([['a', 1], ['c', 3]]);
834+
* const symmetricDifference = col1.symmetricDifference(col2);
835+
* console.log(col1.symmetricDifference(col2));
836+
* // => Collection { 'b' => 2, 'c' => 3 }
837+
* ```
789838
*/
790-
public difference<T>(other: ReadonlyCollection<K, T>): Collection<K, T | V> {
839+
public symmetricDifference<T>(other: ReadonlyCollection<K, T>): Collection<K, T | V> {
791840
const coll = new this.constructor[Symbol.species]<K, T | V>();
792-
for (const [key, value] of other) {
793-
if (!this.has(key)) coll.set(key, value);
794-
}
795841

796842
for (const [key, value] of this) {
797843
if (!other.has(key)) coll.set(key, value);
798844
}
799845

846+
for (const [key, value] of other) {
847+
if (!this.has(key)) coll.set(key, value);
848+
}
849+
800850
return coll;
801851
}
802852

0 commit comments

Comments
 (0)
Please sign in to comment.