jupyter-ijavascript-utils 1.43.0 → 1.45.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/DOCS.md +1 -0
- package/Dockerfile +1 -1
- package/README.md +1 -1
- package/package.json +3 -2
- package/src/aggregate.js +82 -0
- package/src/describe.js +10 -0
- package/src/object.js +136 -6
- package/src/set.js +18 -5
package/DOCS.md
CHANGED
|
@@ -75,6 +75,7 @@ Give it a try here:
|
|
|
75
75
|
|
|
76
76
|
## What's New
|
|
77
77
|
|
|
78
|
+
* 1.45 - more ways to understand the data - {@link module:aggregate.coalesce|aggregate.coalesce()}, convert properties to arrow/dot notation / reverse it {@link module:object.flatten|object.flatten()} / {@link module:object.expand|object.expand()} and {@link module:object.isObject|object.isObject()}
|
|
78
79
|
* 1.43 - esm module fix since still not supported yet in ijavascript
|
|
79
80
|
* 1.41 - {@link module:object.propertyInherit|object.propertyInherit} - to simplify inheriting values from one record to the next
|
|
80
81
|
* 1.40 - {@link module:array.extract|array.extract} and {@link module:array.applyArrayValues|array.applyArrayValues} to allow for extracting values from arrays, transforming them on a separate process and applying them deeply and safely
|
package/Dockerfile
CHANGED
package/README.md
CHANGED
|
@@ -54,7 +54,7 @@ This is not intended to be the only way to accomplish many of these tasks, and a
|
|
|
54
54
|

|
|
55
55
|
|
|
56
56
|
# What's New
|
|
57
|
-
|
|
57
|
+
* 1.45 - more ways to understand the data - aggregate.coalesce(), convert properties to arrow/dot notation / reverse it : object.flatten() / object.expand() and Object.isObject()
|
|
58
58
|
* 1.43 - esm module fix since still not supported yet in ijavascript
|
|
59
59
|
* 1.41 - object.propertyInherit - to simplify inheriting values from one record to the next
|
|
60
60
|
* 1.40 - array.extract and array.applyArrayValue to allow for extracting values from arrays, transforming them on a separate process and applying them back
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jupyter-ijavascript-utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.45.0",
|
|
4
4
|
"description": "Utilities for working with iJavaScript - a Jupyter Kernel",
|
|
5
5
|
"homepage": "https://jupyter-ijavascript-utils.onrender.com/",
|
|
6
6
|
"license": "MIT",
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"test:debug": "TZ=UTC node --inspect-brk node_modules/jest/bin/jest.js --runInBand",
|
|
18
18
|
"test:coverage": "TZ=UTC jest src --collectCoverage",
|
|
19
19
|
"test:watch:coverage": "TZ=UTC jest src --watch --collectCoverage",
|
|
20
|
-
"doc:taffy": "
|
|
20
|
+
"doc:taffy": "cp -R tmp/taffydb node_modules",
|
|
21
|
+
"doc:taffy:install": "npm install taffydb && npm run doc",
|
|
21
22
|
"docs": "npm run doc",
|
|
22
23
|
"doc": "npm run prep:docdash && node_modules/.bin/jsdoc -c ./jsdoc.json -u ./tutorials ./DOCS.md",
|
|
23
24
|
"prep:docdash": "cp docResources/docdash/layout.tmpl node_modules/docdash/tmpl/layout.tmpl && rm -rf docResources/notebooks/node_modules",
|
package/src/aggregate.js
CHANGED
|
@@ -38,6 +38,7 @@ const FormatUtils = require('./format');
|
|
|
38
38
|
* * {@link module:aggregate.length|length()} - Number of records found in the collection
|
|
39
39
|
* * {@link module:aggregate.first|first()} - returns first non-null/undefined in list
|
|
40
40
|
* * {@link module:aggregate.sum|sum()} - sum of a collection
|
|
41
|
+
* * {@link module:aggregate.coalesce|coalesce()} - given a list of objects, creates a single object with first non-null value of all properties
|
|
41
42
|
* * Functional
|
|
42
43
|
* * {@link module:aggregate.deferCollection|deferCollection(function, bindArg, bindArg, ...)} - bind a function with arguments
|
|
43
44
|
* * Percentile
|
|
@@ -389,6 +390,87 @@ module.exports.sum = function sum(collection, accessor) {
|
|
|
389
390
|
return collection.reduce((current, val) => current + cleanedFunc(val), 0);
|
|
390
391
|
};
|
|
391
392
|
|
|
393
|
+
module.exports.coalesceDefaultEvaluationFn = function coalesceDefaultEvaluationFn(
|
|
394
|
+
entryValue,
|
|
395
|
+
currentCoalescedValue,
|
|
396
|
+
entryPropName,
|
|
397
|
+
entry
|
|
398
|
+
) {
|
|
399
|
+
if (currentCoalescedValue) return false;
|
|
400
|
+
if (entryValue == null) return false;
|
|
401
|
+
if (entryValue === 0) return false;
|
|
402
|
+
if (Array.isArray(entryValue) && entryValue.length === 0) return false;
|
|
403
|
+
if (entryValue instanceof Date && entryValue.getTime() === 0) return false;
|
|
404
|
+
return true;
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Coalesces a collection of objects to return a single object that has the first non-null value
|
|
409
|
+
* of all unique properties found in the collection.
|
|
410
|
+
*
|
|
411
|
+
* example:
|
|
412
|
+
*
|
|
413
|
+
* ```
|
|
414
|
+
* collection = [
|
|
415
|
+
* { first: 'john' },
|
|
416
|
+
* { last: 'doe' },
|
|
417
|
+
* { age: 23 }
|
|
418
|
+
* ];
|
|
419
|
+
* utils.agg.coalesce(collection);
|
|
420
|
+
* // { first: 'john', last: 'doe', age: 23 };
|
|
421
|
+
* ```
|
|
422
|
+
*
|
|
423
|
+
* this also works to show example values for a large number of objects
|
|
424
|
+
*
|
|
425
|
+
* ```
|
|
426
|
+
* collection = [
|
|
427
|
+
* { first: 'john', last: 'doe', age: 23, failedClass: null },
|
|
428
|
+
* { first: 'jane', last: 'doe', favouriteColor: 'blue', failedClass: null },
|
|
429
|
+
* null,
|
|
430
|
+
* { first: 'bill', favouriteColor: 'red', failedClass: 'asbx-dx2' }
|
|
431
|
+
* ];
|
|
432
|
+
* utils.agg.coalesce(collection);
|
|
433
|
+
* //-- now we can understand the types of values we got for each property type
|
|
434
|
+
* // { first: 'john', last: 'doe', age: 23, favouriteColor: 'blue', failedClass: 'asbx-dx2' }
|
|
435
|
+
* ```
|
|
436
|
+
*
|
|
437
|
+
* Note - an optional evaluationFn can be provided, that can be used to determine
|
|
438
|
+
* if a value is collected.
|
|
439
|
+
*
|
|
440
|
+
* ```
|
|
441
|
+
* collection = [{ val: null }, { val: 23 }, { val: 2 }, { val: 100 }];
|
|
442
|
+
* maxCoalesce = (val, current) => val && (!current || val > current);
|
|
443
|
+
* utils.agg.coalesce(collection, maxCoalesce);
|
|
444
|
+
* // { val: 100 }
|
|
445
|
+
* ```
|
|
446
|
+
*
|
|
447
|
+
* @param {Array} collection -
|
|
448
|
+
* @param {Function} [evaluationFn] - optional function that defines the value collected
|
|
449
|
+
* - function(entryValue:any, currentCoalescedValue:any, entryPropName:string, entry:Object):Boolean
|
|
450
|
+
* @returns {Object} - Object with all properties found, and the first
|
|
451
|
+
* @see {@link module:describe.describeObjects|describe.describeObjects(collection, options)} - to better understand values found
|
|
452
|
+
*/
|
|
453
|
+
module.exports.coalesce = function coalesce(collection, evaluationFn) {
|
|
454
|
+
if (!Array.isArray(collection)) return collection;
|
|
455
|
+
const cleanEvalFn = evaluationFn || AggregateUtils.coalesceDefaultEvaluationFn;
|
|
456
|
+
|
|
457
|
+
const result = {};
|
|
458
|
+
|
|
459
|
+
collection.forEach((entry) => {
|
|
460
|
+
if (ObjectUtils.isObject(entry)) {
|
|
461
|
+
Object.keys(entry).forEach((key) => {
|
|
462
|
+
const entryValue = entry[key];
|
|
463
|
+
const currentCoalescedValue = result[key];
|
|
464
|
+
if (cleanEvalFn(entryValue, currentCoalescedValue, key, entry)) {
|
|
465
|
+
result[key] = entryValue;
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
return result;
|
|
472
|
+
};
|
|
473
|
+
|
|
392
474
|
/**
|
|
393
475
|
* The difference between the lowest and the highest values in the collection
|
|
394
476
|
*
|
package/src/describe.js
CHANGED
|
@@ -14,6 +14,12 @@ const ObjectUtils = require('./object');
|
|
|
14
14
|
* * {@link module:describe.describeNumbers|describeNumbers(collection, options)} - describes a series of numbers
|
|
15
15
|
* * {@link module:describe.describeDates|describeDates(collection, options)} - describes a series of dates
|
|
16
16
|
*
|
|
17
|
+
* Most commonly, {@link module:describe.describeObjects|object.describeObjects(collection, options)} is used -
|
|
18
|
+
* as it describes with the appropriate type for each property.
|
|
19
|
+
*
|
|
20
|
+
* Note, if there are multiple child objects within the collection, {@link module:object.flatten|object.flatten()}
|
|
21
|
+
* will bring those values down through dot notation (similar to arrow format) - so they can be better described.
|
|
22
|
+
*
|
|
17
23
|
* @module describe
|
|
18
24
|
* @exports describe
|
|
19
25
|
*/
|
|
@@ -500,6 +506,9 @@ class DateDescription extends SeriesDescription {
|
|
|
500
506
|
* age |number|3 |25 |23 |24 | | |
|
|
501
507
|
* enrolled|Date |3 |2022-01-05T00:00:00.000Z|2022-01-01T00:00:00.000Z|2022-01-03T00:00:00.000Z| | |
|
|
502
508
|
*
|
|
509
|
+
* Note, if there are multiple child objects within the collection, {@link module:object.flatten|object.flatten()}
|
|
510
|
+
* will bring those values down through dot notation (similar to arrow format) - so they can be better described.
|
|
511
|
+
*
|
|
503
512
|
* @param {Object[]} collection - Collection of objects to be described
|
|
504
513
|
* @param {Object} options - options to be used
|
|
505
514
|
* @param {String[]} options.include - string list of fields to include in the description
|
|
@@ -508,6 +517,7 @@ class DateDescription extends SeriesDescription {
|
|
|
508
517
|
* - that will override how that property is parsed.
|
|
509
518
|
* @param {Number} maxRows - max rows to consider before halting
|
|
510
519
|
* @returns {SeriesDescription[]} - collection of descriptions - one for each property
|
|
520
|
+
* @see {@link module:object.flatten|object.flatten()} - if the collection of objects have a large number of child objects.
|
|
511
521
|
*/
|
|
512
522
|
module.exports.describeObjects = function describeObjects(collection, options) {
|
|
513
523
|
const cleanCollection = Array.isArray(collection) ? collection : [collection];
|
package/src/object.js
CHANGED
|
@@ -8,6 +8,7 @@ const FormatUtils = require('./format');
|
|
|
8
8
|
* Utility for working with and massaging javascript objects.
|
|
9
9
|
*
|
|
10
10
|
* * Describe objects
|
|
11
|
+
* * {@link module:object.isObject|isObject()} - Determine if a given value is an Object and not a Number, String, Array or Date
|
|
11
12
|
* * {@link module:object.keys|keys()} - Safely get the keys of an object or list of objects
|
|
12
13
|
* * {@link module:object.getObjectPropertyTypes|getObjectPropertyTypes()} - describe the properties of a list of objects
|
|
13
14
|
* * {@link module:object.generateSchema|generateSchema()} - generate a schema / describe properties of a list of objects
|
|
@@ -45,8 +46,9 @@ const FormatUtils = require('./format');
|
|
|
45
46
|
* * {@link module:object.cleanPropertyName|cleanPropertyName()} - create a translation of a specific property name to be accessible.
|
|
46
47
|
* * {@link module:object.renameProperties|renameProperties()} - Use a translation from old property names to new ones
|
|
47
48
|
* * Flatten object properties
|
|
48
|
-
* * {@link module:object.
|
|
49
|
-
* * {@link module:object.
|
|
49
|
+
* * {@link module:object.collapse|collapse()} - coalesce properties from all nested objects to the base object.
|
|
50
|
+
* * {@link module:object.flatten|flatten()} - creates dot notation properties (similar to arrow notation) of all child objects.
|
|
51
|
+
* * {@link module:object.expand|expand()} - expands dot notation properties onto sub children (inverse of flatten)
|
|
50
52
|
* * Create Map of objects by key
|
|
51
53
|
* * {@link module:object.mapByProperty|mapByProperty()} -
|
|
52
54
|
* * {@link module:group.by|group(collection, accessor)}
|
|
@@ -463,12 +465,138 @@ const collapseSpecificObject = function collapseSpecificObject(sourceObj, target
|
|
|
463
465
|
* // 'Hi John, how do you like your F150?
|
|
464
466
|
* @param {Object} objectTree
|
|
465
467
|
* @returns {Object} - object with all the properties added
|
|
466
|
-
* @see #MAX_COLLAPSE_DEPTH -
|
|
468
|
+
* @see #MAX_COLLAPSE_DEPTH - library property that defines how far to collapse
|
|
467
469
|
*/
|
|
468
470
|
module.exports.collapse = function collapse(targetObj) {
|
|
469
471
|
return collapseSpecificObject({}, targetObj, 0);
|
|
470
472
|
};
|
|
471
473
|
|
|
474
|
+
/**
|
|
475
|
+
* Determines whether a value is an Object and not an Array or a Date
|
|
476
|
+
* @param {any} testValue - value to be tested
|
|
477
|
+
* @returns {Boolean} - whether the testValue is an Object and not an Array or a Date.
|
|
478
|
+
*/
|
|
479
|
+
module.exports.isObject = (o) => o != null
|
|
480
|
+
&& typeof o === 'object'
|
|
481
|
+
&& !Array.isArray(o)
|
|
482
|
+
&& !(o instanceof Date);
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* While originally intended as a sub-implementation for Flatten,
|
|
486
|
+
* this was exposed in case additional cases ever arose.
|
|
487
|
+
*
|
|
488
|
+
* Example:
|
|
489
|
+
*
|
|
490
|
+
* ```
|
|
491
|
+
* student = { first: 'john', last: 'doe' };
|
|
492
|
+
* friend = { first: 'jane', last: 'doe' };
|
|
493
|
+
* course = { id: 'econ-101', professor: { id: 10101, first: 'jim', last: 'gifford' }};
|
|
494
|
+
* flattenedObj = {};
|
|
495
|
+
* flattenedObj = utils.object.flattenObjectOntoAnother(student, flattenedObj);
|
|
496
|
+
* // { first: 'john', last: 'doe' }
|
|
497
|
+
* flattenedObj = utils.object.flattenObjectOntoAnother(friend, flattenedObj, 'friend.');
|
|
498
|
+
* // { first: 'john', last: 'doe', 'friend.first': 'jane', 'friend.last': 'doe' };
|
|
499
|
+
* flattenedObj = utils.object.flattenObjectOntoAnother(course, flattenedObj, 'course.');
|
|
500
|
+
* // { first: 'john', last: 'doe', 'friend.first': 'jane', 'friend.last': 'doe', 'course.id': 'econ-101',
|
|
501
|
+
* // 'course.professor.id': 10101, 'course.professor.first': 'jim', 'course.professor.last': 'gifford' };
|
|
502
|
+
* ```
|
|
503
|
+
*
|
|
504
|
+
* See flatten for a an alternative to achieve the same result.
|
|
505
|
+
*
|
|
506
|
+
* @param {Object} sourceObj - The object to review for source values / properties
|
|
507
|
+
* @param {Object} [targetObj={}] - The object to apply the dot notation properties onto
|
|
508
|
+
* @param {String} [prefix=''] - the string prefix of any properties found on source, to apply onto target
|
|
509
|
+
* @returns {Object} - the targetObj with the properties applied (in place)
|
|
510
|
+
*/
|
|
511
|
+
module.exports.flattenObjectOntoAnother = function flattenObjectOntoAnother(sourceObj, targetObj, prefix) {
|
|
512
|
+
const cleanTarget = targetObj || {};
|
|
513
|
+
const cleanPrefix = prefix || '';
|
|
514
|
+
|
|
515
|
+
if (!ObjectUtils.isObject(sourceObj)) {
|
|
516
|
+
return sourceObj;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
const sourceKeys = ObjectUtils.keys(sourceObj);
|
|
520
|
+
|
|
521
|
+
sourceKeys.forEach((key) => {
|
|
522
|
+
const prefixedKey = `${cleanPrefix}${key}`;
|
|
523
|
+
const keyValue = sourceObj[key];
|
|
524
|
+
if (ObjectUtils.isObject(keyValue)) {
|
|
525
|
+
ObjectUtils.flattenObjectOntoAnother(keyValue, cleanTarget, `${prefixedKey}.`);
|
|
526
|
+
} else {
|
|
527
|
+
cleanTarget[prefixedKey] = keyValue;
|
|
528
|
+
}
|
|
529
|
+
});
|
|
530
|
+
return cleanTarget;
|
|
531
|
+
};
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Flattens an object and sub-objects into dot notation - to have easier time understanding schemas and explainations.
|
|
535
|
+
*
|
|
536
|
+
* example:
|
|
537
|
+
*
|
|
538
|
+
* ```
|
|
539
|
+
* student = {
|
|
540
|
+
* first: 'john', last: 'doe',
|
|
541
|
+
* friend: { first: 'jane', last: 'doe' },
|
|
542
|
+
* course: { id: 'econ-101', professor: { id: 10101, first: 'jim', last: 'gifford' }}
|
|
543
|
+
* };
|
|
544
|
+
*
|
|
545
|
+
* flattenedObj = utils.object.flatten(student);
|
|
546
|
+
* // {
|
|
547
|
+
* // first: 'john', last: 'doe',
|
|
548
|
+
* // 'friend.first': 'jane', 'friend.last': 'doe',
|
|
549
|
+
* // 'course.id': 'econ-101',
|
|
550
|
+
* // 'course.professor.id': 10101, 'course.professor.first': 'jim', 'course.professor.last': 'gifford'
|
|
551
|
+
* // };
|
|
552
|
+
* ```
|
|
553
|
+
* @param {Object} targetObj - Object with all properties and sub-objects to flatten.
|
|
554
|
+
* @returns {Object} - New object with dot notation properties
|
|
555
|
+
* @see {@link module:object.expand|expand()} - as the inverse
|
|
556
|
+
* @see {@link module:describe.describeObjects|describeObjects(collection, options)} - as a way to describe the values provided
|
|
557
|
+
*/
|
|
558
|
+
module.exports.flatten = function flatten(targetObj) {
|
|
559
|
+
return ObjectUtils.flattenObjectOntoAnother(targetObj);
|
|
560
|
+
};
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* The inverse of Flatten - this takes an object with dot notation properties,
|
|
564
|
+
* and creates the sub-objects as necessary to contain the properties defined.
|
|
565
|
+
*
|
|
566
|
+
* Example:
|
|
567
|
+
*
|
|
568
|
+
* ```
|
|
569
|
+
* flattenedObj = {
|
|
570
|
+
* first: 'john', last: 'doe',
|
|
571
|
+
* 'friend.first': 'jane', 'friend.last': 'doe',
|
|
572
|
+
* 'course.id': 'econ-101',
|
|
573
|
+
* 'course.professor.id': 10101, 'course.professor.first': 'jim', 'course.professor.last': 'gifford'
|
|
574
|
+
* };
|
|
575
|
+
*
|
|
576
|
+
* expandedObj = utils.object.expand(flattenedObj);
|
|
577
|
+
* // {
|
|
578
|
+
* // first: 'john', last: 'doe',
|
|
579
|
+
* // friend: { first: 'jane', last: 'doe' },
|
|
580
|
+
* // course: { id: 'econ-101', professor: { id: 10101, first: 'jim', last: 'gifford' }}
|
|
581
|
+
* // };
|
|
582
|
+
* ```
|
|
583
|
+
*
|
|
584
|
+
* @param {Object} targetObj - a flattened object (with dot notation properties) to be expanded
|
|
585
|
+
* @returns {Object} - a new object with sub-objects for each of the dot-notation entries
|
|
586
|
+
* @see {@link module:object.flatten|flatten()} - as the inverse
|
|
587
|
+
*/
|
|
588
|
+
module.exports.expand = function expand(targetObj) {
|
|
589
|
+
if (!ObjectUtils.isObject(targetObj)) return targetObj;
|
|
590
|
+
|
|
591
|
+
const result = {};
|
|
592
|
+
const keys = ObjectUtils.keys(targetObj);
|
|
593
|
+
keys.forEach((key) => {
|
|
594
|
+
ObjectUtils.applyPropertyValue(result, key, targetObj[key]);
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
return result;
|
|
598
|
+
};
|
|
599
|
+
|
|
472
600
|
/**
|
|
473
601
|
* Keeps only specific properties on an object or list of objects
|
|
474
602
|
* @param {Object | Object[]} list - collection of objects to filter
|
|
@@ -1429,9 +1557,11 @@ module.exports.mapProperties = function mapProperties(objCollection, formattingF
|
|
|
1429
1557
|
? [objCollection]
|
|
1430
1558
|
: objCollection;
|
|
1431
1559
|
|
|
1432
|
-
const cleanProperties = propertiesToFormat.length
|
|
1433
|
-
?
|
|
1434
|
-
: propertiesToFormat
|
|
1560
|
+
const cleanProperties = propertiesToFormat.length === 0
|
|
1561
|
+
? ObjectUtils.keys(objCollection)
|
|
1562
|
+
: propertiesToFormat.length > 0 && Array.isArray(propertiesToFormat[0])
|
|
1563
|
+
? propertiesToFormat[0]
|
|
1564
|
+
: propertiesToFormat;
|
|
1435
1565
|
|
|
1436
1566
|
if (typeof formattingFn !== 'function') {
|
|
1437
1567
|
throw Error('object.mapProperties(collection, formattingFn, ...propertiesToFormat): formattingFn must be provided');
|
package/src/set.js
CHANGED
|
@@ -27,11 +27,13 @@ const SetUtils = module.exports;
|
|
|
27
27
|
/**
|
|
28
28
|
* Mutably adds a value to a set, and then returns the set. (Allowing Chaining)
|
|
29
29
|
*
|
|
30
|
-
* (If you wish to immutably, use ES6: `{...setA, value1, value2, ...setB, etc...}
|
|
30
|
+
* (If you wish to immutably, use ES6: `{...setA, value1, value2, ...setB, etc...}`<br />
|
|
31
|
+
* or use the {@link module:set.union|union(set, list|set|iterable)} command below)
|
|
31
32
|
*
|
|
32
33
|
* @param {set} setTarget - set to add values to
|
|
33
34
|
* @param {any} val - value to add to the set
|
|
34
35
|
* @returns {set} setTarget
|
|
36
|
+
* @see {@link module:set.union|union(set, list|set|iterable)}
|
|
35
37
|
* @example
|
|
36
38
|
* setA = new Set([1, 2, 3]);
|
|
37
39
|
* utils.array.add(setA, 4, 5, 6); // Set([1, 2, 3, 4, 5, 6])
|
|
@@ -50,7 +52,8 @@ module.exports.add = function add(setTarget, ...rest) {
|
|
|
50
52
|
*
|
|
51
53
|
* @param {set} setTarget - set to add values to
|
|
52
54
|
* @param {iteratable} iteratable - iteratable that can be unioned into the set.
|
|
53
|
-
* @
|
|
55
|
+
* @param {...iteratable} rest - additional iteratables to add to the union
|
|
56
|
+
* @returns {set} new set that contains values from all sources
|
|
54
57
|
* @example
|
|
55
58
|
*
|
|
56
59
|
* setA = new Set([1, 2, 3]);
|
|
@@ -61,8 +64,12 @@ module.exports.add = function add(setTarget, ...rest) {
|
|
|
61
64
|
* listB = [4, 5, 6];
|
|
62
65
|
* array.union(setA, listB) // Set([1, 2, 3, 4, 5, 6])
|
|
63
66
|
*
|
|
67
|
+
* setC = new Set([7, 8, 9]);
|
|
68
|
+
* array.union(setA, listB, setC);
|
|
69
|
+
* // Set(1, 2, 3, 4, 5, 6, 7, 8, 9);
|
|
70
|
+
*
|
|
64
71
|
*/
|
|
65
|
-
module.exports.union = function union(setTarget, iteratable) {
|
|
72
|
+
module.exports.union = function union(setTarget, iteratable, ...rest) {
|
|
66
73
|
const target = setTarget instanceof Set ? setTarget : new Set(setTarget);
|
|
67
74
|
if (iteratable) {
|
|
68
75
|
// eslint-disable-next-line
|
|
@@ -70,6 +77,7 @@ module.exports.union = function union(setTarget, iteratable) {
|
|
|
70
77
|
target.add(v);
|
|
71
78
|
}
|
|
72
79
|
}
|
|
80
|
+
if (rest.length > 0) return SetUtils.union.apply(this, [target, ...rest]);
|
|
73
81
|
return target;
|
|
74
82
|
};
|
|
75
83
|
|
|
@@ -80,7 +88,8 @@ module.exports.union = function union(setTarget, iteratable) {
|
|
|
80
88
|
*
|
|
81
89
|
* @param {Set} sourceA - the set to check for common items
|
|
82
90
|
* @param {Set} sourceB - another set to check for common items
|
|
83
|
-
* @
|
|
91
|
+
* @param {...iteratable} rest - additional iteratables to verify
|
|
92
|
+
* @returns {Set} - set of items that are in all sources
|
|
84
93
|
* @example
|
|
85
94
|
* setA = new Set([1, 2, 3, 4]);
|
|
86
95
|
* setB = new Set([3, 4, 5, 6]);
|
|
@@ -88,10 +97,14 @@ module.exports.union = function union(setTarget, iteratable) {
|
|
|
88
97
|
*
|
|
89
98
|
* // Note that you can use other iteratable things too
|
|
90
99
|
* utils.set.intersection([1, 2, 3, 4], [3, 4, 5, 6]); // Set([3, 4])
|
|
100
|
+
*
|
|
101
|
+
* setC = new Set([3, 4, 9, 10]);
|
|
102
|
+
* utils.set.intersection(setA, setB, setC); // Set([3, 4]);
|
|
91
103
|
*/
|
|
92
|
-
module.exports.intersection = function intersection(sourceA, sourceB) {
|
|
104
|
+
module.exports.intersection = function intersection(sourceA, sourceB, ...rest) {
|
|
93
105
|
const targetA = sourceA instanceof Set ? sourceA : new Set(sourceA);
|
|
94
106
|
const results = new Set([...sourceB].filter((val) => targetA.has(val)));
|
|
107
|
+
if (rest.length > 0) return SetUtils.intersection.apply(this, [results, ...rest]);
|
|
95
108
|
return results;
|
|
96
109
|
};
|
|
97
110
|
|