Skip to content

Commit 0db63be

Browse files
committed
Dynamic Comparators
1 parent ad76e78 commit 0db63be

9 files changed

+361
-5
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Change Log
22

3+
<a name="4.4.3"></a>
4+
# [4.4.3](https://github.com/larrydiamond/typescriptcollectionsframework/compare/v4.4.2...v4.4.3) (2019-01-30)
5+
* Dynamic Comparator - this eases the creation of comparators to make constructing sorted Collections easier - the node.js tutorial will have examples shortly!
6+
37
<a name="4.4.2"></a>
48
# [4.4.2](https://github.com/larrydiamond/typescriptcollectionsframework/compare/v4.4.1...v4.4.2) (2019-01-19)
59
* Map JSON.stringify rewrite to provide much better output. Better handling of complex generic maps for JSON.stringify

definitions/src/Collections.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ export declare class Collections {
6060
* This method creates a Hashable for a class and prevents you from having to copy and paste and then test and debug all the boilerplate code
6161
*/
6262
static dynamicHashable<K>(...values: string[]): Hashable<K>;
63+
/**
64+
* This method creates a Comparator for a class and prevents you from having to copy and paste and then test and debug all the boilerplate code
65+
*/
66+
static dynamicComparator<K>(...values: string[]): Comparator<K>;
67+
private static booleanCompare;
68+
private static numberCompare;
69+
private static stringCompare;
6370
/**
6471
* Returns an Array of the elements of this Immutable Collection
6572
*/

dist/spec/TestCollections.spec.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,61 @@ describe("Test Collections static methods", function () {
311311
jasts_2.TestNumber.notEquals("psp2 hashcode is non-zero", nameHashable.hashCode(psp2), 0);
312312
jasts_2.TestNumber.notEquals("psp3 hashcode is non-zero", nameHashable.hashCode(psp3), 0);
313313
});
314+
it("Dynamic Comparator number field", function () {
315+
var nc = Collections_1.Collections.dynamicComparator("sku");
316+
jasts_2.TestNumber.equals("same null object equals itself", nc.compare(pspnull, pspnull), 0);
317+
jasts_2.TestNumber.equals("different null object equals itself", nc.compare(pspnull, pspalsonull), 0);
318+
jasts_2.TestNumber.equals("same undefined object equals itself", nc.compare(pspundefined, pspundefined), 0);
319+
jasts_2.TestNumber.equals("different undefined object equals itself", nc.compare(pspundefined, pspalsoundefined), 0);
320+
jasts_2.TestNumber.equals("undefined is less than null", nc.compare(pspundefined, pspnull), -1);
321+
jasts_2.TestNumber.equals("null is more than undefined", nc.compare(pspnull, pspundefined), 1);
322+
jasts_2.TestNumber.equals("undefined is less than a value", nc.compare(pspundefined, psp1), -1);
323+
jasts_2.TestNumber.equals("a value is more than undefined", nc.compare(psp1, pspundefined), 1);
324+
jasts_2.TestNumber.equals("null is less than a value", nc.compare(pspnull, psp1), -1);
325+
jasts_2.TestNumber.equals("a value is more than null", nc.compare(psp1, pspnull), 1);
326+
jasts_2.TestNumber.equals("same value equals itself", nc.compare(psp1, psp1), 0);
327+
jasts_2.TestNumber.equals("different object with same value equals itself", nc.compare(psp1, psp1copy), 0); // sku = 1
328+
jasts_2.TestNumber.equals("higher values are higher than lower values", nc.compare(psp2, psp1), 1);
329+
jasts_2.TestNumber.equals("lower values are lower than higher values", nc.compare(psp1, psp2), -1);
330+
});
331+
it("Dynamic Comparator string field", function () {
332+
var nc = Collections_1.Collections.dynamicComparator("name");
333+
jasts_2.TestNumber.equals("same null object equals itself", nc.compare(pspnull, pspnull), 0);
334+
jasts_2.TestNumber.equals("different null object equals itself", nc.compare(pspnull, pspalsonull), 0);
335+
jasts_2.TestNumber.equals("same undefined object equals itself", nc.compare(pspundefined, pspundefined), 0);
336+
jasts_2.TestNumber.equals("different undefined object equals itself", nc.compare(pspundefined, pspalsoundefined), 0);
337+
jasts_2.TestNumber.equals("undefined is less than null", nc.compare(pspundefined, pspnull), -1);
338+
jasts_2.TestNumber.equals("null is more than undefined", nc.compare(pspnull, pspundefined), 1);
339+
jasts_2.TestNumber.equals("undefined is less than a value", nc.compare(pspundefined, psp1), -1);
340+
jasts_2.TestNumber.equals("a value is more than undefined", nc.compare(psp1, pspundefined), 1);
341+
jasts_2.TestNumber.equals("null is less than a value", nc.compare(pspnull, psp1), -1);
342+
jasts_2.TestNumber.equals("a value is more than null", nc.compare(psp1, pspnull), 1);
343+
jasts_2.TestNumber.equals("same value equals itself", nc.compare(psp1, psp1), 0);
344+
jasts_2.TestNumber.equals("different object with same value equals itself", nc.compare(psp1, psp3copy), 0); // name = A
345+
jasts_2.TestNumber.equals("higher values are higher than lower values", nc.compare(psp2, psp1), 1);
346+
jasts_2.TestNumber.equals("lower values are lower than higher values", nc.compare(psp1, psp2), -1);
347+
});
348+
it("Dynamic Comparator compound number string", function () {
349+
var nc = Collections_1.Collections.dynamicComparator("sku", "name");
350+
jasts_2.TestNumber.equals("same null object equals itself", nc.compare(pspnull, pspnull), 0);
351+
jasts_2.TestNumber.equals("different null object equals itself", nc.compare(pspnull, pspalsonull), 0);
352+
jasts_2.TestNumber.equals("same undefined object equals itself", nc.compare(pspundefined, pspundefined), 0);
353+
jasts_2.TestNumber.equals("different undefined object equals itself", nc.compare(pspundefined, pspalsoundefined), 0);
354+
jasts_2.TestNumber.equals("undefined is less than null", nc.compare(pspundefined, pspnull), -1);
355+
jasts_2.TestNumber.equals("null is more than undefined", nc.compare(pspnull, pspundefined), 1);
356+
jasts_2.TestNumber.equals("undefined is less than a value", nc.compare(pspundefined, psp1), -1);
357+
jasts_2.TestNumber.equals("a value is more than undefined", nc.compare(psp1, pspundefined), 1);
358+
jasts_2.TestNumber.equals("null is less than a value", nc.compare(pspnull, psp1), -1);
359+
jasts_2.TestNumber.equals("a value is more than null", nc.compare(psp1, pspnull), 1);
360+
jasts_2.TestNumber.equals("same value equals itself", nc.compare(psp1, psp1), 0);
361+
jasts_2.TestNumber.equals("different value with same keys equals itself", nc.compare(psp1, psp3copy), 0); // Sku 1 Name A
362+
jasts_2.TestNumber.equals("higher values on first field are higher than lower values", nc.compare(psp2, psp1), 1);
363+
jasts_2.TestNumber.equals("lower values on first field are lower than higher values", nc.compare(psp1, psp2), -1);
364+
jasts_2.TestNumber.equals("higher values on first field outweigh second field", nc.compare(psp2copy, psp1copy), 1);
365+
jasts_2.TestNumber.equals("lower values on first field outweigh second field", nc.compare(psp1copy, psp2copy), -1);
366+
jasts_2.TestNumber.equals("higher values on second field", nc.compare(psp1copy, psp3copy), 1);
367+
jasts_2.TestNumber.equals("lower values on second field", nc.compare(psp3copy, psp1copy), -1);
368+
});
314369
});
315370
/*
316371
* This class is a simple class that the default Collectable
@@ -333,3 +388,5 @@ var psp2copy = new PetStoreProduct(5, "B", "E"); // duplicate product name
333388
var psp3copy = new PetStoreProduct(1, "A", "F"); // duplicate sku and product name
334389
var pspnull = new PetStoreProduct(null, null, null);
335390
var pspundefined = new PetStoreProduct(undefined, undefined, undefined);
391+
var pspalsonull = new PetStoreProduct(null, null, null);
392+
var pspalsoundefined = new PetStoreProduct(undefined, undefined, undefined);

dist/spec/TestNavigableSet.spec.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ var alphabeticalSortPetStoreProduct = {
5353
return 1;
5454
}
5555
};
56+
var productnameComparator = Collections_1.Collections.dynamicComparator("productName");
5657
var product2 = new PetStoreProduct("ChewToy", 14.99);
5758
var product1 = new PetStoreProduct("Catnip", 4.99);
5859
var product3 = new PetStoreProduct("Goldfish", 9.99);
@@ -115,11 +116,17 @@ describe("Test NavigableSet functionality", function () {
115116
testJavaIteration(new NavigableHash_1.NavigableHashSet(alphabeticalSortPetStoreProduct));
116117
testJavaIteration(new TreeSet_1.TreeSet(alphabeticalSortPetStoreProduct));
117118
testJavaIteration(new SkipList_1.SkipListSet(alphabeticalSortPetStoreProduct));
119+
testJavaIteration(new NavigableHash_1.NavigableHashSet(productnameComparator));
120+
testJavaIteration(new TreeSet_1.TreeSet(productnameComparator));
121+
testJavaIteration(new SkipList_1.SkipListSet(productnameComparator));
118122
});
119123
it("Set Test typescript iteration", function () {
120124
testTSIteration(new NavigableHash_1.NavigableHashSet(alphabeticalSortPetStoreProduct));
121125
testTSIteration(new TreeSet_1.TreeSet(alphabeticalSortPetStoreProduct));
122126
testTSIteration(new SkipList_1.SkipListSet(alphabeticalSortPetStoreProduct));
127+
testTSIteration(new NavigableHash_1.NavigableHashSet(productnameComparator));
128+
testTSIteration(new TreeSet_1.TreeSet(productnameComparator));
129+
testTSIteration(new SkipList_1.SkipListSet(productnameComparator));
123130
});
124131
});
125132
function testFirstKeyNumber(set) {

dist/src/Collections.js

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,108 @@ var Collections = /** @class */ (function () {
311311
};
312312
return tmp;
313313
};
314+
/**
315+
* This method creates a Comparator for a class and prevents you from having to copy and paste and then test and debug all the boilerplate code
316+
*/
317+
Collections.dynamicComparator = function () {
318+
var values = [];
319+
for (var _i = 0; _i < arguments.length; _i++) {
320+
values[_i] = arguments[_i];
321+
}
322+
var tmp = {
323+
compare: function (o1, o2) {
324+
if (o1 === undefined) {
325+
if (o2 === undefined) {
326+
return 0;
327+
}
328+
else {
329+
return -1;
330+
}
331+
}
332+
if (o2 === undefined)
333+
return 1;
334+
if (o1 === null) {
335+
if (o2 === null) {
336+
return 0;
337+
}
338+
else {
339+
return -1;
340+
}
341+
}
342+
if (o2 === null)
343+
return 1;
344+
for (var loop = 0; loop < values.length; loop++) {
345+
var a = o1[values[loop]];
346+
var b = o2[values[loop]];
347+
if (a === undefined) {
348+
if (b === undefined) {
349+
return 0;
350+
}
351+
else {
352+
return -1;
353+
}
354+
}
355+
if (b === undefined)
356+
return 1;
357+
if (a === null) {
358+
if (b === null) {
359+
return 0;
360+
}
361+
else {
362+
return -1;
363+
}
364+
}
365+
if (b === null)
366+
return 1;
367+
if (typeof a === "boolean") {
368+
var x = Collections.booleanCompare(a, b);
369+
if (x !== 0)
370+
return x;
371+
}
372+
else {
373+
if (typeof a === "string") {
374+
var x = Collections.stringCompare(a, b);
375+
if (x !== 0)
376+
return x;
377+
}
378+
else {
379+
if (typeof a === "number") {
380+
var x = Collections.numberCompare(a, b);
381+
if (x !== 0)
382+
return x;
383+
}
384+
else {
385+
// other types?
386+
}
387+
}
388+
}
389+
}
390+
return 0;
391+
}
392+
};
393+
return tmp;
394+
};
395+
Collections.booleanCompare = function (a, b) {
396+
if (a === b) {
397+
return 0;
398+
}
399+
if (a === false) {
400+
return -1;
401+
}
402+
return 1;
403+
};
404+
Collections.numberCompare = function (a, b) {
405+
if (a === b) {
406+
return 0;
407+
}
408+
if (a < b) {
409+
return -1;
410+
}
411+
return 1;
412+
};
413+
Collections.stringCompare = function (a, b) {
414+
return a.localeCompare(b);
415+
};
314416
/**
315417
* Returns an Array of the elements of this Immutable Collection
316418
*/

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
"merge2": "^1.2.3",
1919
"mixin-deep": "^2.0.0",
2020
"standard-version": "^4.4.0",
21-
"tslint": "^5.12.0",
22-
"typedoc": "^0.14.0",
23-
"typescript": "^3.2.2"
21+
"tslint": "^5.12.1",
22+
"typedoc": "^0.14.2",
23+
"typescript": "^3.2.4"
2424
},
2525
"main": "dist/index.js",
2626
"nyc": {

spec/TestCollections.spec.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,67 @@ describe("Test Collections static methods", function() {
381381
TestNumber.notEquals ("psp2 hashcode is non-zero", nameHashable.hashCode(psp2), 0);
382382
TestNumber.notEquals ("psp3 hashcode is non-zero", nameHashable.hashCode(psp3), 0);
383383
});
384+
385+
it ("Dynamic Comparator number field", function () {
386+
const nc:Comparator<PetStoreProduct> = Collections.dynamicComparator<PetStoreProduct>("sku");
387+
TestNumber.equals ("same null object equals itself", nc.compare(pspnull, pspnull), 0);
388+
TestNumber.equals ("different null object equals itself", nc.compare(pspnull, pspalsonull), 0);
389+
TestNumber.equals ("same undefined object equals itself", nc.compare(pspundefined, pspundefined), 0);
390+
TestNumber.equals ("different undefined object equals itself", nc.compare(pspundefined, pspalsoundefined), 0);
391+
TestNumber.equals ("undefined is less than null", nc.compare(pspundefined, pspnull), -1);
392+
TestNumber.equals ("null is more than undefined", nc.compare(pspnull, pspundefined), 1);
393+
TestNumber.equals ("undefined is less than a value", nc.compare(pspundefined, psp1), -1);
394+
TestNumber.equals ("a value is more than undefined", nc.compare(psp1, pspundefined), 1);
395+
TestNumber.equals ("null is less than a value", nc.compare(pspnull, psp1), -1);
396+
TestNumber.equals ("a value is more than null", nc.compare(psp1, pspnull), 1);
397+
TestNumber.equals ("same value equals itself", nc.compare(psp1, psp1), 0);
398+
TestNumber.equals ("different object with same value equals itself", nc.compare(psp1, psp1copy), 0); // sku = 1
399+
TestNumber.equals ("higher values are higher than lower values", nc.compare(psp2, psp1), 1);
400+
TestNumber.equals ("lower values are lower than higher values", nc.compare(psp1, psp2), -1);
401+
});
402+
403+
it ("Dynamic Comparator string field", function () {
404+
const nc:Comparator<PetStoreProduct> = Collections.dynamicComparator<PetStoreProduct>("name");
405+
TestNumber.equals ("same null object equals itself", nc.compare(pspnull, pspnull), 0);
406+
TestNumber.equals ("different null object equals itself", nc.compare(pspnull, pspalsonull), 0);
407+
TestNumber.equals ("same undefined object equals itself", nc.compare(pspundefined, pspundefined), 0);
408+
TestNumber.equals ("different undefined object equals itself", nc.compare(pspundefined, pspalsoundefined), 0);
409+
TestNumber.equals ("undefined is less than null", nc.compare(pspundefined, pspnull), -1);
410+
TestNumber.equals ("null is more than undefined", nc.compare(pspnull, pspundefined), 1);
411+
TestNumber.equals ("undefined is less than a value", nc.compare(pspundefined, psp1), -1);
412+
TestNumber.equals ("a value is more than undefined", nc.compare(psp1, pspundefined), 1);
413+
TestNumber.equals ("null is less than a value", nc.compare(pspnull, psp1), -1);
414+
TestNumber.equals ("a value is more than null", nc.compare(psp1, pspnull), 1);
415+
TestNumber.equals ("same value equals itself", nc.compare(psp1, psp1), 0);
416+
TestNumber.equals ("different object with same value equals itself", nc.compare(psp1, psp3copy), 0); // name = A
417+
TestNumber.equals ("higher values are higher than lower values", nc.compare(psp2, psp1), 1);
418+
TestNumber.equals ("lower values are lower than higher values", nc.compare(psp1, psp2), -1);
419+
});
420+
421+
it ("Dynamic Comparator compound number string", function () {
422+
const nc:Comparator<PetStoreProduct> = Collections.dynamicComparator<PetStoreProduct>("sku", "name");
423+
TestNumber.equals ("same null object equals itself", nc.compare(pspnull, pspnull), 0);
424+
TestNumber.equals ("different null object equals itself", nc.compare(pspnull, pspalsonull), 0);
425+
TestNumber.equals ("same undefined object equals itself", nc.compare(pspundefined, pspundefined), 0);
426+
TestNumber.equals ("different undefined object equals itself", nc.compare(pspundefined, pspalsoundefined), 0);
427+
TestNumber.equals ("undefined is less than null", nc.compare(pspundefined, pspnull), -1);
428+
TestNumber.equals ("null is more than undefined", nc.compare(pspnull, pspundefined), 1);
429+
TestNumber.equals ("undefined is less than a value", nc.compare(pspundefined, psp1), -1);
430+
TestNumber.equals ("a value is more than undefined", nc.compare(psp1, pspundefined), 1);
431+
TestNumber.equals ("null is less than a value", nc.compare(pspnull, psp1), -1);
432+
TestNumber.equals ("a value is more than null", nc.compare(psp1, pspnull), 1);
433+
TestNumber.equals ("same value equals itself", nc.compare(psp1, psp1), 0);
434+
TestNumber.equals ("different value with same keys equals itself", nc.compare(psp1, psp3copy), 0); // Sku 1 Name A
435+
436+
TestNumber.equals ("higher values on first field are higher than lower values", nc.compare(psp2, psp1), 1);
437+
TestNumber.equals ("lower values on first field are lower than higher values", nc.compare(psp1, psp2), -1);
438+
439+
TestNumber.equals ("higher values on first field outweigh second field", nc.compare(psp2copy, psp1copy), 1);
440+
TestNumber.equals ("lower values on first field outweigh second field", nc.compare(psp1copy, psp2copy), -1);
441+
442+
TestNumber.equals ("higher values on second field", nc.compare(psp1copy, psp3copy), 1);
443+
TestNumber.equals ("lower values on second field", nc.compare(psp3copy, psp1copy), -1);
444+
});
384445
});
385446

386447
/*
@@ -410,3 +471,5 @@ const psp3copy:PetStoreProduct = new PetStoreProduct (1, "A", "F"); // duplicat
410471

411472
const pspnull:PetStoreProduct = new PetStoreProduct (null, null, null);
412473
const pspundefined:PetStoreProduct = new PetStoreProduct (undefined, undefined, undefined);
474+
const pspalsonull:PetStoreProduct = new PetStoreProduct (null, null, null);
475+
const pspalsoundefined:PetStoreProduct = new PetStoreProduct (undefined, undefined, undefined);

0 commit comments

Comments
 (0)