@vbarbarosh/node-helpers 3.57.0 → 3.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "author": "Vladimir Barbarosh <vladimir.barbarosh@gmail.com>",
3
3
  "license": "MIT",
4
4
  "name": "@vbarbarosh/node-helpers",
5
- "version": "3.57.0",
5
+ "version": "3.58.0",
6
6
  "description": "A set of helpers for JavaScript/Node.js",
7
7
  "files": [
8
8
  "src"
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Create fcmp from an array of props. For desc order a prop should be prefixed with minus sign (e.g. -price).
3
+ */
4
+ function fcmp_from_spec(props)
5
+ {
6
+ const fcmp = props.map(one);
7
+ switch (fcmp.length) {
8
+ case 0:
9
+ return () => 0;
10
+ case 1:
11
+ return fcmp[0];
12
+ case 2:
13
+ return function (a, b) {
14
+ return fcmp[0](a, b) || fcmp[1](a, b);
15
+ };
16
+ case 3:
17
+ return function (a, b) {
18
+ return fcmp[0](a, b) || fcmp[1](a, b) || fcmp[2](a, b);
19
+ };
20
+ default:
21
+ return function (a, b) {
22
+ for (let i = 0; i < fcmp.length; ++i) {
23
+ const tmp = fcmp[i](a, b);
24
+ if (tmp) {
25
+ return tmp;
26
+ }
27
+ }
28
+ return 0;
29
+ };
30
+ }
31
+ }
32
+
33
+ function one(prop)
34
+ {
35
+ if (prop[0] === '-') {
36
+ prop = prop.slice(1);
37
+ return function (b, a) {
38
+ return comp_types(a[prop], b[prop]);
39
+ };
40
+ }
41
+ return function (a, b) {
42
+ return comp_types(a[prop], b[prop]);
43
+ };
44
+ }
45
+
46
+ function comp_types(a, b)
47
+ {
48
+ const ta = typeof a;
49
+ const tb = typeof b;
50
+ if (ta === 'string' && ta === tb) {
51
+ return a.localeCompare(b);
52
+ }
53
+ return a - b;
54
+ }
55
+
56
+ module.exports = fcmp_from_spec;
@@ -0,0 +1,91 @@
1
+ const assert = require('assert');
2
+ const fcmp_from_spec = require('./fcmp_from_spec');
3
+
4
+ describe('fcmp_from_spec', function () {
5
+ it('basic [id] • sort by id (asc)', function () {
6
+ const actual = [
7
+ {id: 3, name: 'Banana', price: 8.25},
8
+ {id: 1, name: 'Apple', price: 10.99},
9
+ {id: 2, name: 'Cherry', price: 15.49},
10
+ ];
11
+ actual.sort(fcmp_from_spec(['id']));
12
+ const expected = [
13
+ {id: 1, name: 'Apple', price: 10.99},
14
+ {id: 2, name: 'Cherry', price: 15.49},
15
+ {id: 3, name: 'Banana', price: 8.25},
16
+ ];
17
+ assert.deepStrictEqual(actual, expected);
18
+ });
19
+ it('basic [-id] • sort by id (desc)', function () {
20
+ const actual = [
21
+ {id: 3, name: 'Banana', price: 8.25},
22
+ {id: 1, name: 'Apple', price: 10.99},
23
+ {id: 2, name: 'Cherry', price: 15.49},
24
+ ];
25
+ actual.sort(fcmp_from_spec(['-id']));
26
+ const expected = [
27
+ {id: 3, name: 'Banana', price: 8.25},
28
+ {id: 2, name: 'Cherry', price: 15.49},
29
+ {id: 1, name: 'Apple', price: 10.99},
30
+ ];
31
+ assert.deepStrictEqual(actual, expected);
32
+ });
33
+ it('basic [name] • sort by name (asc)', function () {
34
+ const actual = [
35
+ {id: 3, name: 'Banana', price: 8.25},
36
+ {id: 1, name: 'Apple', price: 10.99},
37
+ {id: 2, name: 'Cherry', price: 15.49},
38
+ ];
39
+ actual.sort(fcmp_from_spec(['name']));
40
+ const expected = [
41
+ {id: 1, name: 'Apple', price: 10.99},
42
+ {id: 3, name: 'Banana', price: 8.25},
43
+ {id: 2, name: 'Cherry', price: 15.49},
44
+ ];
45
+ assert.deepStrictEqual(actual, expected);
46
+ });
47
+ it('basic [-name] • sort by name (desc)', function () {
48
+ const actual = [
49
+ {id: 3, name: 'Banana', price: 8.25},
50
+ {id: 1, name: 'Apple', price: 10.99},
51
+ {id: 2, name: 'Cherry', price: 15.49},
52
+ ];
53
+ actual.sort(fcmp_from_spec(['-name']));
54
+ const expected = [
55
+ {id: 2, name: 'Cherry', price: 15.49},
56
+ {id: 3, name: 'Banana', price: 8.25},
57
+ {id: 1, name: 'Apple', price: 10.99},
58
+ ];
59
+ assert.deepStrictEqual(actual, expected);
60
+ });
61
+ it('compound [price,name] • sort by price (asc), name (asc)', function () {
62
+ const actual = [
63
+ {id: 1, name: 'Apple', price: 10.99},
64
+ {id: 2, name: 'Cherry', price: 10.99},
65
+ {id: 3, name: 'Banana', price: 8.25},
66
+ ];
67
+ actual.sort(fcmp_from_spec(['price', 'name']));
68
+ const expected = [
69
+ {id: 3, name: 'Banana', price: 8.25},
70
+ {id: 1, name: 'Apple', price: 10.99},
71
+ {id: 2, name: 'Cherry', price: 10.99},
72
+ ];
73
+ assert.deepStrictEqual(actual, expected);
74
+ });
75
+ it('compound [-price,name,id] • sort by price (desc), name (asc), id (asc)', function () {
76
+ const actual = [
77
+ {id: 1, name: 'Apple', price: 10.99},
78
+ {id: 2, name: 'Cherry', price: 15.49},
79
+ {id: 3, name: 'Banana', price: 8.25},
80
+ {id: 4, name: 'Banana', price: 8.25},
81
+ ];
82
+ actual.sort(fcmp_from_spec(['-price', 'name', 'id']));
83
+ const expected = [
84
+ {id: 2, name: 'Cherry', price: 15.49},
85
+ {id: 1, name: 'Apple', price: 10.99},
86
+ {id: 3, name: 'Banana', price: 8.25},
87
+ {id: 4, name: 'Banana', price: 8.25},
88
+ ];
89
+ assert.deepStrictEqual(actual, expected);
90
+ });
91
+ });