some-common-functions-js 1.1.2 → 1.1.3
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/README.md +72 -34
- package/index.js +39 -10
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -134,6 +134,30 @@ console.log(emptyObj);
|
|
|
134
134
|
*/
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
+
### `unset(anObject, path)`
|
|
138
|
+
Remove a field from an object at the specified path.
|
|
139
|
+
Can take the place of lodash unset() function.
|
|
140
|
+
|
|
141
|
+
***Example***
|
|
142
|
+
```
|
|
143
|
+
const {unset} = require("some-common-functions-js");
|
|
144
|
+
let testObj = {
|
|
145
|
+
firstName: 'John',
|
|
146
|
+
lastName: 'Rambo',
|
|
147
|
+
address: { country: { name: 'South Africa', code: 'ZA' } }
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
unset(testObj, "address.country.code");
|
|
151
|
+
unset(testObj, "lastName");
|
|
152
|
+
console.log(testObj); // Expecting to have "address.country.code" and "lastName" removed.
|
|
153
|
+
/*
|
|
154
|
+
{
|
|
155
|
+
firstName: 'John',
|
|
156
|
+
address: { country: { name: 'South Africa' } }
|
|
157
|
+
}
|
|
158
|
+
*/
|
|
159
|
+
```
|
|
160
|
+
|
|
137
161
|
### `hasOnly(anObject, ...fields)`
|
|
138
162
|
Returns `true` if the object contains **only** some or all of the specified fields and no others.
|
|
139
163
|
|
|
@@ -460,59 +484,73 @@ Create an array of objects with duplicates eliminated. Taking only the first or
|
|
|
460
484
|
***Example***
|
|
461
485
|
```
|
|
462
486
|
const { getObjArrayWithNoDuplicates } = require("some-common-functions-js");
|
|
463
|
-
let teamsArray = [
|
|
464
|
-
{ score: 90, numGames: 10 },
|
|
465
|
-
{ score: 90, numGames: 10 },
|
|
466
|
-
{ score: 90, numGames: 10 },
|
|
467
|
-
{ score: 90, numGames: 12 },
|
|
468
|
-
{ score: 90, numGames: 12 },
|
|
469
|
-
{ score: 90, numGames: 12 },
|
|
470
|
-
{ score: 85, numGames: 8 },
|
|
471
|
-
{ score: 85, numGames: 8 },
|
|
472
|
-
{ score: 85, numGames: 10 },
|
|
473
|
-
{ score: 85, numGames: 10 },
|
|
474
|
-
{ score: 85, numGames: 10 }
|
|
487
|
+
let teamsArray = [
|
|
488
|
+
{ score: 90, numGames: 10, name: "John" },
|
|
489
|
+
{ score: 90, numGames: 10, name: "Jane" },
|
|
490
|
+
{ score: 90, numGames: 10, name: "Bob" },
|
|
491
|
+
{ score: 90, numGames: 12, name: "Alice" },
|
|
492
|
+
{ score: 90, numGames: 12, name: "Charlie" },
|
|
493
|
+
{ score: 90, numGames: 12, name: "David" },
|
|
494
|
+
{ score: 85, numGames: 8, name: "Eve" },
|
|
495
|
+
{ score: 85, numGames: 8, name: "Frank" },
|
|
496
|
+
{ score: 85, numGames: 10, name: "Grace" },
|
|
497
|
+
{ score: 85, numGames: 10, name: "Henry" },
|
|
498
|
+
{ score: 85, numGames: 10, name: "Ivy" }
|
|
475
499
|
]; // Sorted by "score desc", "numGames asc".
|
|
476
500
|
|
|
477
501
|
let noDuplicatesArray = getObjArrayWithNoDuplicates(teamsArray, true, "score desc", "numGames asc");
|
|
478
|
-
console.log(noDuplicatesArray);
|
|
502
|
+
console.log(noDuplicatesArray);
|
|
503
|
+
// Should contain only unique objects according to comparison fields. First object per duplicate group.
|
|
479
504
|
/*
|
|
480
|
-
[
|
|
481
|
-
{ score: 90, numGames: 10 },
|
|
482
|
-
{ score: 90, numGames: 12 },
|
|
483
|
-
{ score: 85, numGames: 8 },
|
|
484
|
-
{ score: 85, numGames: 10 }
|
|
485
|
-
]
|
|
505
|
+
[
|
|
506
|
+
{ score: 90, numGames: 10, name: 'John' },
|
|
507
|
+
{ score: 90, numGames: 12, name: 'Alice' },
|
|
508
|
+
{ score: 85, numGames: 8, name: 'Eve' },
|
|
509
|
+
{ score: 85, numGames: 10, name: 'Grace' }
|
|
510
|
+
]
|
|
486
511
|
*/
|
|
512
|
+
|
|
513
|
+
let noDuplicatesArray = getObjArrayWithNoDuplicates(teamsArray, true, "score desc", "numGames asc");
|
|
514
|
+
console.log(noDuplicatesArray);
|
|
515
|
+
// Should contain unique objects according to comparison fields. Last object per duplicate group.
|
|
516
|
+
/*
|
|
517
|
+
[
|
|
518
|
+
{ score: 90, numGames: 10, name: 'Bob' },
|
|
519
|
+
{ score: 90, numGames: 12, name: 'David' },
|
|
520
|
+
{ score: 85, numGames: 8, name: 'Frank' },
|
|
521
|
+
{ score: 85, numGames: 10, name: 'Ivy' }
|
|
522
|
+
]
|
|
523
|
+
*/
|
|
487
524
|
```
|
|
488
525
|
|
|
489
526
|
### `getNextDifferent(objArray, targetObj, startFrom, ...comparisonFields)`
|
|
490
527
|
Get the index in the array of objects, of the next element that is distinct from the target object.
|
|
491
|
-
Comparison fields must match the field & sort order of the object array.
|
|
528
|
+
Comparison fields must match the field & sort order of the object array.
|
|
529
|
+
Throw an error if the target object is greater than objArray[startFrom] in terms of sort order.
|
|
492
530
|
Examples of comparison fields: "firstName", "lastName desc", "address.province asc", "address.townOrCity".
|
|
493
531
|
|
|
494
532
|
***Example***
|
|
495
533
|
```
|
|
496
|
-
const {
|
|
534
|
+
const { getNextDifferent } = require("some-common-functions-js");
|
|
497
535
|
|
|
498
536
|
teamsArray = [
|
|
499
|
-
{ score: 90, numGames: 10 },
|
|
500
|
-
{ score: 90, numGames: 10 },
|
|
501
|
-
{ score: 90, numGames: 10 },
|
|
502
|
-
{ score: 90, numGames: 12 },
|
|
503
|
-
{ score: 90, numGames: 12 },
|
|
504
|
-
{ score: 90, numGames: 12 },
|
|
505
|
-
{ score: 85, numGames: 8 },
|
|
506
|
-
{ score: 85, numGames: 8 },
|
|
507
|
-
{ score: 85, numGames: 10 },
|
|
508
|
-
{ score: 85, numGames: 10 },
|
|
509
|
-
{ score: 85, numGames: 10 }
|
|
537
|
+
{ score: 90, numGames: 10, name: "John" },
|
|
538
|
+
{ score: 90, numGames: 10, name: "Jane" },
|
|
539
|
+
{ score: 90, numGames: 10, name: "Bob" },
|
|
540
|
+
{ score: 90, numGames: 12, name: "Alice" },
|
|
541
|
+
{ score: 90, numGames: 12, name: "Charlie" },
|
|
542
|
+
{ score: 90, numGames: 12, name: "David" },
|
|
543
|
+
{ score: 85, numGames: 8, name: "Eve" },
|
|
544
|
+
{ score: 85, numGames: 8, name: "Frank" },
|
|
545
|
+
{ score: 85, numGames: 10, name: "Grace" },
|
|
546
|
+
{ score: 85, numGames: 10, name: "Henry" },
|
|
547
|
+
{ score: 85, numGames: 10, name: "Ivy" }
|
|
510
548
|
]; // Sorted by "score desc", "numGames asc".
|
|
511
549
|
|
|
512
|
-
let next =
|
|
550
|
+
let next = getNextDifferent(teamsArray, { score: 85, numGames: 8 }, 0, "score desc", "numGames asc");
|
|
513
551
|
// Throws an error because the startFrom index is to the left ('less than') the target object in terms of the field sort order.
|
|
514
552
|
|
|
515
|
-
next =
|
|
553
|
+
next = getNextDifferent(teamsArray, { score: 90, numGames: 10 }, 0, "score desc", "numGames asc");
|
|
516
554
|
// 3
|
|
517
555
|
|
|
518
556
|
|
package/index.js
CHANGED
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
* 2025/11/28 ITA 1.01 Added function hasOnlyAll().
|
|
6
6
|
* 2025/12/22 ITA 1.02 Improved documentation of the functions and moved in more functions.
|
|
7
7
|
* 2025/12/30 ITA 1.03 Removed lodash dependency by re-implementing get() and set() object functions, significantly reducing this package size.
|
|
8
|
-
* Added function getNextDifferent() to deal better with duplicate removal from arrays of objects.
|
|
8
|
+
* Added function getNextDifferent() to deal better with duplicate removal from arrays of objects.
|
|
9
|
+
* 2026/01/02 ITA 1.04 Improved the functions getNoDuplicatesArray() and getNextDifferent() to handle more test cases.
|
|
10
|
+
* Added function unset().
|
|
9
11
|
*/
|
|
10
12
|
|
|
11
13
|
/**Return true if userName is valid
|
|
@@ -266,10 +268,6 @@ module.exports.get = get;
|
|
|
266
268
|
* @param {*} value the value to set.
|
|
267
269
|
*/
|
|
268
270
|
function set(anObject, path, value) {
|
|
269
|
-
/*if (hasAll(anObject, path) === false) {
|
|
270
|
-
throw new Error(`Path ${path} does not exist on the object.`);
|
|
271
|
-
}*/
|
|
272
|
-
|
|
273
271
|
let paths = path.split('.');
|
|
274
272
|
if (paths.length > 1) {
|
|
275
273
|
if (!anObject[paths[0]]) {
|
|
@@ -285,6 +283,24 @@ function set(anObject, path, value) {
|
|
|
285
283
|
}
|
|
286
284
|
module.exports.set = set;
|
|
287
285
|
|
|
286
|
+
/** Unset the value of a field specified by the path on an object.
|
|
287
|
+
* @param {object} anObject a Javascript object.
|
|
288
|
+
* @param {string} path a path specifying the field whose value is to be set.
|
|
289
|
+
* @param {*} value the value to set.
|
|
290
|
+
*/
|
|
291
|
+
function unset(anObject, path) {
|
|
292
|
+
let paths = path.split('.');
|
|
293
|
+
if (paths.length > 1) {
|
|
294
|
+
const subObject = anObject[paths[0]];
|
|
295
|
+
paths.splice(0, 1);
|
|
296
|
+
unset(subObject, paths.join('.'));
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
delete anObject[paths[0]];
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
module.exports.unset = unset;
|
|
303
|
+
|
|
288
304
|
/**
|
|
289
305
|
* Determine whether an object contains only 1, some or all of the specified fields, and not any other fields.
|
|
290
306
|
* @param {object} anObject a Javascript object.
|
|
@@ -466,9 +482,14 @@ function getNextDifferent(objArray, targetObj, startFrom, ...comparisonFields) {
|
|
|
466
482
|
let start = startFrom,
|
|
467
483
|
end = objArray.length - 1;
|
|
468
484
|
|
|
485
|
+
|
|
486
|
+
if (start >= objArray.length) { // throw error if startFrom is outside the bounds of the array.
|
|
487
|
+
throw new Error('startFrom is outside the bounds of the array.');
|
|
488
|
+
}
|
|
469
489
|
// If target object is to the right of objArray[start], then throw an error..
|
|
470
|
-
if (objCompare(targetObj, objArray[start], ...comparisonFields) > 0)
|
|
490
|
+
if (objCompare(targetObj, objArray[start], ...comparisonFields) > 0) {
|
|
471
491
|
throw new Error('targetObj is to the right (\'greater than\') objArray[startFrom].');
|
|
492
|
+
}
|
|
472
493
|
|
|
473
494
|
while (start < end) {
|
|
474
495
|
let mid = Math.trunc((start + end) / 2);
|
|
@@ -507,7 +528,7 @@ function getObjArrayWithNoDuplicates(objArray, firstOfDuplicates, ...comparisonF
|
|
|
507
528
|
throw new Error(`firstOfDuplicates must be boolean true or false.`);
|
|
508
529
|
|
|
509
530
|
const noDuplicates = [];
|
|
510
|
-
let idx;
|
|
531
|
+
let idx = 0;
|
|
511
532
|
let grpStart = 0; // Start index of current duplicate group.
|
|
512
533
|
while (grpStart < objArray.length - 1) {
|
|
513
534
|
if (firstOfDuplicates) {
|
|
@@ -524,9 +545,17 @@ function getObjArrayWithNoDuplicates(objArray, firstOfDuplicates, ...comparisonF
|
|
|
524
545
|
}
|
|
525
546
|
idx = grpStart;
|
|
526
547
|
}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
548
|
+
if (noDuplicates.length === 0) { // All objects are duplicates.
|
|
549
|
+
if (firstOfDuplicates)
|
|
550
|
+
noDuplicates.push(objArray[0]);
|
|
551
|
+
else
|
|
552
|
+
noDuplicates.push(objArray[objArray.length - 1]);
|
|
553
|
+
}
|
|
554
|
+
else {
|
|
555
|
+
if (objCompare(noDuplicates[noDuplicates.length - 1], objArray[objArray.length - 1], ...comparisonFields) !== 0) {
|
|
556
|
+
noDuplicates.push(objArray[objArray.length - 1]);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
530
559
|
|
|
531
560
|
return noDuplicates;
|
|
532
561
|
} // function getObjArrayWithNoDuplicates(objArray, ...comparisonFields) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "some-common-functions-js",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "Common functions used with Javascript objects, and field validation functions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"validation",
|
|
@@ -23,14 +23,14 @@
|
|
|
23
23
|
"object utilities",
|
|
24
24
|
"object validation",
|
|
25
25
|
"object array search",
|
|
26
|
-
"object
|
|
26
|
+
"object compare",
|
|
27
27
|
"nodejs"
|
|
28
28
|
],
|
|
29
29
|
"repository": {
|
|
30
30
|
"type": "git",
|
|
31
31
|
"url": "https://github.com/IsaiahTshabalala/common-functions"
|
|
32
32
|
},
|
|
33
|
-
"license": "
|
|
33
|
+
"license": "MIT",
|
|
34
34
|
"author": "ITA",
|
|
35
35
|
"type": "commonjs",
|
|
36
36
|
"main": "index.js",
|