@codady/utils 0.0.10 → 0.0.11
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/CHANGELOG.md +17 -0
- package/dist/utils.cjs.js +256 -3
- package/dist/utils.cjs.min.js +3 -3
- package/dist/utils.esm.js +256 -3
- package/dist/utils.esm.min.js +3 -3
- package/dist/utils.umd - /345/211/257/346/234/254.js" +749 -0
- package/dist/utils.umd.js +258 -7
- package/dist/utils.umd.min.js +3 -3
- package/dist.zip +0 -0
- package/modules.js +14 -2
- package/modules.ts +14 -2
- package/package.json +1 -1
- package/src/deepClone.js +1 -1
- package/src/deepClone.ts +1 -1
- package/src/deepEqual.js +48 -0
- package/src/deepEqual.ts +46 -0
- package/src/deepMerge.js +34 -0
- package/src/deepMerge.ts +40 -0
- package/src/deepMergeArrays.js +45 -0
- package/src/deepMergeArrays.ts +62 -0
- package/src/deepMergeHelper.js +40 -0
- package/src/deepMergeHelper.ts +45 -0
- package/src/deepMergeMaps - /345/211/257/346/234/254.js" +78 -0
- package/src/deepMergeMaps.js +57 -0
- package/src/deepMergeMaps.ts +67 -0
- package/src/deepMergeObjects.js +82 -0
- package/src/deepMergeObjects.ts +85 -0
- package/src/deepMergeSets.js +48 -0
- package/src/deepMergeSets.ts +55 -0
package/dist/utils.umd.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
|
-
* @since Last modified: 2025-12-
|
|
3
|
+
* @since Last modified: 2025-12-24 17:50:8
|
|
4
4
|
* @name Utils for web front-end.
|
|
5
|
-
* @version 0.0.
|
|
5
|
+
* @version 0.0.11
|
|
6
6
|
* @author AXUI development team <3217728223@qq.com>
|
|
7
7
|
* @description This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.
|
|
8
8
|
* @see {@link https://www.axui.cn|Official website}
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
(function (global, factory) {
|
|
18
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
19
|
-
typeof define === 'function' && define.amd ? define(factory) :
|
|
20
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.utils = factory());
|
|
21
|
-
})(this, (function () { 'use strict';
|
|
18
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('assert')) :
|
|
19
|
+
typeof define === 'function' && define.amd ? define(['assert'], factory) :
|
|
20
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.utils = factory(global.assert));
|
|
21
|
+
})(this, (function (assert) { 'use strict';
|
|
22
22
|
|
|
23
23
|
const getDataType = (obj) => {
|
|
24
24
|
let tmp = Object.prototype.toString.call(obj).slice(8, -1), result;
|
|
@@ -426,6 +426,251 @@
|
|
|
426
426
|
return methods;
|
|
427
427
|
};
|
|
428
428
|
|
|
429
|
+
const deepMergeObjects = (target, source, opts = {}) => {
|
|
430
|
+
let targetType = getDataType(target), sourceType = getDataType(source);
|
|
431
|
+
//target不是对象或者source为空则直接返回
|
|
432
|
+
if (targetType !== 'Object' || sourceType !== 'Object') {
|
|
433
|
+
return target;
|
|
434
|
+
}
|
|
435
|
+
const options = Object.assign({ itemMode: 'merge', propAppend: true, targetClone: false, useEnable: true }, opts),
|
|
436
|
+
//如果是复制方法,则先复制target
|
|
437
|
+
result = options.targetClone ? deepClone(target) : target;
|
|
438
|
+
for (let k in source) {
|
|
439
|
+
if (source.hasOwnProperty(k) && result.hasOwnProperty(k)) {
|
|
440
|
+
let resp = deepMergeHelper(result[k], source[k], opts);
|
|
441
|
+
//resp={result,flag,type}
|
|
442
|
+
//flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
|
|
443
|
+
if (!resp.flag) {
|
|
444
|
+
//类型不同则直接覆盖
|
|
445
|
+
if (options.useEnable && result.hasOwnProperty(k) && result[k]?.hasOwnProperty('enable') && typeof source[k] === 'boolean') {
|
|
446
|
+
//部分替换,仅针对result={enable:true/false,a:''},source=false/true这种情况和相反的情况,因为这种情况再笨框架比较多见
|
|
447
|
+
if (result[k]?.hasOwnProperty('enable') && typeof source[k] === 'boolean') {
|
|
448
|
+
//result={enable:true,a:'',b:''},source[k]=false=>result={enable:false,a:'',b:''}
|
|
449
|
+
result[k].enable = source[k];
|
|
450
|
+
}
|
|
451
|
+
else if (source[k]?.hasOwnProperty('enable') && typeof result[k] === 'boolean') {
|
|
452
|
+
//source={enable:true,a:'',b:''},(result as any)[k]=false=>result={enable:false,a:'',b:''}
|
|
453
|
+
result = Object.assign({ enable: result[k] }, source[k]);
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
//完全替换
|
|
457
|
+
result[k] = source[k];
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
else {
|
|
461
|
+
//完全替换
|
|
462
|
+
result[k] = source[k];
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
// If both target and source are objects, merge them recursively
|
|
467
|
+
if (resp.type === 'Object') {
|
|
468
|
+
result[k] = resp.result;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
else if (source.hasOwnProperty(k) && !result.hasOwnProperty(k) && options.propAppend) {
|
|
473
|
+
//如果source有属性,result没有该属性,但是options允许追加属性则直接赋值
|
|
474
|
+
result[k] = source[k];
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
//Symbol键直接追加,因为Symbol是唯一,结果同Object.assign
|
|
478
|
+
if (options.useSymbol) {
|
|
479
|
+
let symbols = Object.getOwnPropertySymbols(source);
|
|
480
|
+
if (symbols.length > 0) {
|
|
481
|
+
for (let k of symbols) {
|
|
482
|
+
result[k] = source[k];
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
return result;
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
const deepMergeArrays = (target, source, options = { itemMode: 'merge', propAppend: true, targetClone: false, useEnable: true }) => {
|
|
490
|
+
// Ensure both target and source are arrays
|
|
491
|
+
if (!Array.isArray(target) || !Array.isArray(source))
|
|
492
|
+
return target;
|
|
493
|
+
// Merge options, with default values
|
|
494
|
+
const opts = Object.assign({ itemMode: 'merge', propAppend: true, targetClone: false }, options),
|
|
495
|
+
// If cloning is enabled, create a deep copy of the target array
|
|
496
|
+
result = opts.targetClone ? [...target] : target;
|
|
497
|
+
// Handle different merge strategies based on itemMode
|
|
498
|
+
if (opts.itemMode === 'replace') {
|
|
499
|
+
// Replace mode: clear the target array and push all items from the source array
|
|
500
|
+
result.length = 0;
|
|
501
|
+
result.push(...source);
|
|
502
|
+
return result;
|
|
503
|
+
}
|
|
504
|
+
else if (opts.itemMode === 'concat') {
|
|
505
|
+
// Concatenate mode: append all items from the source array to the target array
|
|
506
|
+
result.push(...source);
|
|
507
|
+
return result;
|
|
508
|
+
}
|
|
509
|
+
else {
|
|
510
|
+
// Default "merge" mode: recursively merge items in the arrays
|
|
511
|
+
for (let i = 0; i < source.length; i++) {
|
|
512
|
+
let resp = deepMergeHelper(result[i], source[i], opts);
|
|
513
|
+
//resp={result,flag,type}
|
|
514
|
+
//flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
|
|
515
|
+
if (!resp.flag) {
|
|
516
|
+
result[i] = source[i];
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
return result;
|
|
520
|
+
}
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
const deepMergeMaps = (target, source, options = { itemMode: 'merge', propAppend: true, targetClone: false, useEnable: true }) => {
|
|
524
|
+
// Ensure both target and source are Maps
|
|
525
|
+
if (!(target instanceof Map) || !(source instanceof Map))
|
|
526
|
+
return target;
|
|
527
|
+
// Merge options, with default values
|
|
528
|
+
const opts = Object.assign({ itemMode: 'merge', propAppend: true, targetClone: false, useEnable: true }, options),
|
|
529
|
+
// If cloning is enabled, create a deep copy of the target Map
|
|
530
|
+
result = opts.targetClone ? new Map(target) : target;
|
|
531
|
+
// Handle different merge strategies based on itemMode
|
|
532
|
+
if (opts.itemMode === 'replace') {
|
|
533
|
+
// Replace mode: clear the target Map and add all entries from the source Map
|
|
534
|
+
result.clear();
|
|
535
|
+
source.forEach((value, key) => result.set(key, value));
|
|
536
|
+
return result;
|
|
537
|
+
}
|
|
538
|
+
else if (opts.itemMode === 'concat') {
|
|
539
|
+
// Concatenate mode: add all entries from the source Map to the target Map
|
|
540
|
+
source.forEach((value, key) => result.set(key, value));
|
|
541
|
+
return result;
|
|
542
|
+
}
|
|
543
|
+
else {
|
|
544
|
+
// Default "merge" mode: recursively merge entries in the Maps
|
|
545
|
+
source.forEach((value, key) => {
|
|
546
|
+
// Check if the key already exists in the target Map
|
|
547
|
+
if (result.has(key)) {
|
|
548
|
+
const targetValue = result.get(key), sourceValue = value, resp = deepMergeHelper(targetValue, sourceValue, opts);
|
|
549
|
+
//resp={result,flag,type}
|
|
550
|
+
//flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
|
|
551
|
+
if (!resp.flag) {
|
|
552
|
+
// For simple values, overwrite the target value with the source value
|
|
553
|
+
result.set(key, sourceValue);
|
|
554
|
+
}
|
|
555
|
+
else {
|
|
556
|
+
// If both target and source are objects, merge them recursively
|
|
557
|
+
resp.type === 'Object' && result.set(key, resp.result);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
else {
|
|
561
|
+
// If the key doesn't exist in the target, add the entry from the source Map
|
|
562
|
+
result.set(key, value);
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
return result;
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
const deepEqual = (a, b) => {
|
|
570
|
+
// If both are equal by reference
|
|
571
|
+
if (a === b)
|
|
572
|
+
return true;
|
|
573
|
+
// If both are arrays, check equality recursively
|
|
574
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
575
|
+
if (a.length !== b.length)
|
|
576
|
+
return false;
|
|
577
|
+
for (let i = 0; i < a.length; i++) {
|
|
578
|
+
if (!deepEqual(a[i], b[i]))
|
|
579
|
+
return false;
|
|
580
|
+
}
|
|
581
|
+
return true;
|
|
582
|
+
}
|
|
583
|
+
// If both are objects, check equality recursively
|
|
584
|
+
if (typeof a === 'object' && typeof b === 'object') {
|
|
585
|
+
const keysA = Object.keys(a), keysB = Object.keys(b);
|
|
586
|
+
if (keysA.length !== keysB.length)
|
|
587
|
+
return false;
|
|
588
|
+
for (let key of keysA) {
|
|
589
|
+
if (!keysB.includes(key) || !deepEqual(a[key], b[key]))
|
|
590
|
+
return false;
|
|
591
|
+
}
|
|
592
|
+
return true;
|
|
593
|
+
}
|
|
594
|
+
// For other types, direct comparison
|
|
595
|
+
return a === b;
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
const deepMergeSets = (target, source, options = { itemMode: 'merge', propAppend: true, targetClone: false, useEnable: true }) => {
|
|
599
|
+
// Ensure both target and source are Sets
|
|
600
|
+
if (!(target instanceof Set) || !(source instanceof Set))
|
|
601
|
+
return target;
|
|
602
|
+
// Merge options, with default values
|
|
603
|
+
const opts = Object.assign({ itemMode: 'merge', propAppend: true, targetClone: false, useEnable: true }, options),
|
|
604
|
+
// If cloning is enabled, create a deep copy of the target Set
|
|
605
|
+
result = opts.targetClone ? new Set(target) : target;
|
|
606
|
+
// Handle different merge strategies based on itemMode
|
|
607
|
+
if (opts.itemMode === 'replace') {
|
|
608
|
+
// Replace mode: clear the target Set and add all items from the source Set
|
|
609
|
+
result.clear();
|
|
610
|
+
for (let item of source)
|
|
611
|
+
result.add(item);
|
|
612
|
+
return result;
|
|
613
|
+
}
|
|
614
|
+
else if (opts.itemMode === 'concat') {
|
|
615
|
+
// Concatenate mode: add all items from the source Set to the target Set
|
|
616
|
+
for (let item of source)
|
|
617
|
+
result.add(item);
|
|
618
|
+
return result;
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
// Default "merge" mode: recursively merge items in the Sets
|
|
622
|
+
for (let item of source) {
|
|
623
|
+
// Check the type of the target and source items
|
|
624
|
+
let _target = [...result].find(val => deepEqual(val, item)), resp = deepMergeHelper(_target, item, opts);
|
|
625
|
+
//resp={result,flag}
|
|
626
|
+
//flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
|
|
627
|
+
!resp.flag && result.add(item);
|
|
628
|
+
}
|
|
629
|
+
return result;
|
|
630
|
+
}
|
|
631
|
+
};
|
|
632
|
+
|
|
633
|
+
// deepMergeHelper.ts
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
const deepMergeHelper = (target, source, options) => {
|
|
637
|
+
let targetType = getDataType(target), sourceType = getDataType(source), flag = true, type, result;
|
|
638
|
+
if (targetType === 'Object' && sourceType === 'Object') {
|
|
639
|
+
result = deepMergeObjects(target, source, options);
|
|
640
|
+
type = 'Object';
|
|
641
|
+
}
|
|
642
|
+
else if (targetType === 'Array' && sourceType === 'Array') {
|
|
643
|
+
result = deepMergeArrays(target, source, options);
|
|
644
|
+
type = 'Array';
|
|
645
|
+
}
|
|
646
|
+
else if (targetType === 'Set' && sourceType === 'Set') {
|
|
647
|
+
result = deepMergeSets(target, source, options);
|
|
648
|
+
type = 'Set';
|
|
649
|
+
}
|
|
650
|
+
else if (targetType === 'Map' && sourceType === 'Map') {
|
|
651
|
+
result = deepMergeMaps(target, source, options);
|
|
652
|
+
type = 'Map';
|
|
653
|
+
}
|
|
654
|
+
else {
|
|
655
|
+
flag = false;
|
|
656
|
+
result = target; // Default case, replace primitive values
|
|
657
|
+
}
|
|
658
|
+
return {
|
|
659
|
+
result, flag, type
|
|
660
|
+
};
|
|
661
|
+
};
|
|
662
|
+
|
|
663
|
+
const deepMerge = (target, source, opts = {}) => {
|
|
664
|
+
// Get the data types of the target and source
|
|
665
|
+
let options = Object.assign({
|
|
666
|
+
itemMode: 'merge', // Default merge mode
|
|
667
|
+
propAppend: true, // Default to appending properties from source to target
|
|
668
|
+
targetClone: false, // Do not clone target by default
|
|
669
|
+
useEnable: true // Enable special handling for objects with an `enable` property
|
|
670
|
+
}, opts);
|
|
671
|
+
return deepMergeHelper(target, source, options);
|
|
672
|
+
};
|
|
673
|
+
|
|
429
674
|
const utils = {
|
|
430
675
|
//executeStr,
|
|
431
676
|
getDataType,
|
|
@@ -440,7 +685,13 @@
|
|
|
440
685
|
mapMutableMethods,
|
|
441
686
|
wrapSetMethods,
|
|
442
687
|
wrapMapMethods,
|
|
443
|
-
getUniqueId
|
|
688
|
+
getUniqueId,
|
|
689
|
+
deepEqual: assert.deepEqual,
|
|
690
|
+
deepMerge,
|
|
691
|
+
deepMergeArrays,
|
|
692
|
+
deepMergeMaps,
|
|
693
|
+
deepMergeObjects,
|
|
694
|
+
deepMergeSets,
|
|
444
695
|
};
|
|
445
696
|
|
|
446
697
|
return utils;
|
package/dist/utils.umd.min.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @since Last modified: 2025-12-
|
|
2
|
+
* @since Last modified: 2025-12-24 17:50:8
|
|
3
3
|
* @name Utils for web front-end.
|
|
4
|
-
* @version 0.0.
|
|
4
|
+
* @version 0.0.11
|
|
5
5
|
* @author AXUI development team <3217728223@qq.com>
|
|
6
6
|
* @description This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.
|
|
7
7
|
* @see {@link https://www.axui.cn|Official website}
|
|
@@ -12,4 +12,4 @@
|
|
|
12
12
|
* @copyright This software supports the MIT License, allowing free learning and commercial use, but please retain the terms 'ax,' 'axui,' 'AX,' and 'AXUI' within the software.
|
|
13
13
|
* @license MIT license
|
|
14
14
|
*/
|
|
15
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).utils=t()}(this,function(){"use strict";const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),o=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(o.interceptor&&"function"==typeof o.interceptor){let t=o.interceptor(e,r);if(t)return o.onAfterClone?.({output:t,input:e,type:r,cloned:t!==e}),t}o.onBeforeClone?.(e,r);let n,
|
|
15
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("assert")):"function"==typeof define&&define.amd?define(["assert"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).utils=t(e.assert)}(this,function(e){"use strict";const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),o=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(o.interceptor&&"function"==typeof o.interceptor){let t=o.interceptor(e,r);if(t)return o.onAfterClone?.({output:t,input:e,type:r,cloned:t!==e}),t}o.onBeforeClone?.(e,r);let n,a=!0;if("Object"===r&&o.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);for(const r in e)t[r]=deepClone(e[r],o);if(r.length>0)for(const n of r)t[n]=deepClone(e[n],o);n=t}else if("Array"===r&&o.cloneArray)n=e.map(e=>deepClone(e,o));else if("Map"===r&&o.cloneMap){const t=new Map;for(const[r,n]of e)t.set(deepClone(r,o),deepClone(n,o));n=t}else if("Set"===r&&o.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,o));n=t}else if("Date"===r&&o.cloneDate)n=new Date(e.getTime());else if("RegExp"===r&&o.cloneRegex){const t=e;n=new RegExp(t.source,t.flags)}else n=e,a=!1;return o.onAfterClone?.({output:n,input:e,type:r,cloned:a}),n},deepCloneToJSON=e=>{const t=getDataType(e);if("Object"===t){const t={};for(const r in e)t[r]=deepCloneToJSON(e[r]);for(const e in t)void 0===t[e]&&Reflect.deleteProperty(t,e);return t}if("Array"===t){return e.map((e,t)=>deepCloneToJSON(e)).filter(e=>void 0!==e)}return["Number","String","Boolean","Null"].includes(t)?e:void 0},t=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],r=["add","delete","clear"],o=["set","delete","clear"],deepMergeObjects=(e,t,r={})=>{let o=getDataType(e),n=getDataType(t);if("Object"!==o||"Object"!==n)return e;const a=Object.assign({itemMode:"merge",propAppend:!0,targetClone:!1,useEnable:!0},r),s=a.targetClone?deepClone(e):e;for(let e in t)if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){let o=deepMergeHelper(s[e],t[e],r);o.flag?"Object"===o.type&&(s[e]=o.result):a.useEnable&&s.hasOwnProperty(e)&&s[e]?.hasOwnProperty("enable")&&"boolean"==typeof t[e]?s[e]?.hasOwnProperty("enable")&&"boolean"==typeof t[e]?s[e].enable=t[e]:t[e]?.hasOwnProperty("enable")&&"boolean"==typeof s[e]?s=Object.assign({enable:s[e]},t[e]):s[e]=t[e]:s[e]=t[e]}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&a.propAppend&&(s[e]=t[e]);if(a.useSymbol){let e=Object.getOwnPropertySymbols(t);if(e.length>0)for(let r of e)s[r]=t[r]}return s},deepMergeArrays=(e,t,r={itemMode:"merge",propAppend:!0,targetClone:!1,useEnable:!0})=>{if(!Array.isArray(e)||!Array.isArray(t))return e;const o=Object.assign({itemMode:"merge",propAppend:!0,targetClone:!1},r),n=o.targetClone?[...e]:e;if("replace"===o.itemMode)return n.length=0,n.push(...t),n;if("concat"===o.itemMode)return n.push(...t),n;for(let e=0;e<t.length;e++){deepMergeHelper(n[e],t[e],o).flag||(n[e]=t[e])}return n},deepMergeMaps=(e,t,r={itemMode:"merge",propAppend:!0,targetClone:!1,useEnable:!0})=>{if(!(e instanceof Map&&t instanceof Map))return e;const o=Object.assign({itemMode:"merge",propAppend:!0,targetClone:!1,useEnable:!0},r),n=o.targetClone?new Map(e):e;return"replace"===o.itemMode?(n.clear(),t.forEach((e,t)=>n.set(t,e)),n):"concat"===o.itemMode?(t.forEach((e,t)=>n.set(t,e)),n):(t.forEach((e,t)=>{if(n.has(t)){const r=n.get(t),a=e,s=deepMergeHelper(r,a,o);s.flag?"Object"===s.type&&n.set(t,s.result):n.set(t,a)}else n.set(t,e)}),n)},deepEqual=(e,t)=>{if(e===t)return!0;if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(!deepEqual(e[r],t[r]))return!1;return!0}if("object"==typeof e&&"object"==typeof t){const r=Object.keys(e),o=Object.keys(t);if(r.length!==o.length)return!1;for(let n of r)if(!o.includes(n)||!deepEqual(e[n],t[n]))return!1;return!0}return e===t},deepMergeSets=(e,t,r={itemMode:"merge",propAppend:!0,targetClone:!1,useEnable:!0})=>{if(!(e instanceof Set&&t instanceof Set))return e;const o=Object.assign({itemMode:"merge",propAppend:!0,targetClone:!1,useEnable:!0},r),n=o.targetClone?new Set(e):e;if("replace"===o.itemMode){n.clear();for(let e of t)n.add(e);return n}if("concat"===o.itemMode){for(let e of t)n.add(e);return n}for(let e of t){let t=[...n].find(t=>deepEqual(t,e));!deepMergeHelper(t,e,o).flag&&n.add(e)}return n},deepMergeHelper=(e,t,r)=>{let o,n,a=getDataType(e),s=getDataType(t),l=!0;return"Object"===a&&"Object"===s?(n=deepMergeObjects(e,t,r),o="Object"):"Array"===a&&"Array"===s?(n=deepMergeArrays(e,t,r),o="Array"):"Set"===a&&"Set"===s?(n=deepMergeSets(e,t,r),o="Set"):"Map"===a&&"Map"===s?(n=deepMergeMaps(e,t,r),o="Map"):(l=!1,n=e),{result:n,flag:l,type:o}};return{getDataType:getDataType,requireTypes:(e,t,r)=>{let o=Array.isArray(t)?t:[t],n=getDataType(e),a=n.toLowerCase(),s=o.map(e=>e.toLowerCase()),l=a.includes("html")?"element":a;if(r)try{if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`)}catch(e){r(e,n)}else if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`);return n},deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:({target:e,onBeforeMutate:r=()=>{},onAfterMutate:o=()=>{},allowList:n,props:a={}})=>{if(!Array.isArray(e))throw new TypeError("The 'target' parameter must be an array.");n&&!n?.length||(n=t);const s={};for(let t of n)s[t]=function(...n){const s={},l=e.length;switch(t){case"push":case"unshift":s.addedItems=[...n];break;case"pop":s.poppedItem=e[l-1];break;case"shift":s.shiftedItem=e[0];break;case"splice":const[t,r]=n,o=t<0?Math.max(l+t,0):Math.min(t,l),a=void 0===r?l-o:r;s.deletedItems=e.slice(o,o+a);break;case"sort":case"reverse":s.oldSnapshot=[...e];break;case"fill":case"copyWithin":const c=n[1]||0,i=void 0===n[2]?l:n[2];s.oldItems=e.slice(c,i),s.start=c,s.end=i}r?.(s);const c=Array.prototype[t].apply(e,n),i={value:c,key:t,args:n,context:s,target:e,...a};return o?.(i),c};return s},arrayMutableMethods:t,setMutableMethods:r,mapMutableMethods:o,wrapSetMethods:({target:e,onBeforeMutate:t=()=>{},onAfterMutate:o=()=>{},allowList:n=r,props:a={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const s={},createWrappedMethod=r=>function(...n){const s={};switch(r){case"add":{const[t]=n;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=n;s.existed=e.has(t),s.deletedItem=s.existed?t:void 0;break}case"clear":s.clearedItems=Array.from(e),s.previousSize=e.size}t(s);const l=e[r].apply(e,n),c={method:r,result:l,args:n,context:s,target:e,...a};return o(c),l};for(const e of n)r.includes(e)&&(s[e]=createWrappedMethod(e));return Object.defineProperty(s,"target",{get:()=>e,enumerable:!1,configurable:!1}),s},wrapMapMethods:({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:n=o,props:a={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const s={},createWrappedMethod=o=>function(...n){const s={};switch(o){case"set":{const[t,r]=n;s.key=t,s.newValue=r,s.existed=e.has(t),s.oldValue=s.existed?e.get(t):void 0;break}case"delete":{const[t]=n;s.key=t,s.existed=e.has(t),s.value=s.existed?e.get(t):void 0;break}case"clear":s.clearedItems=Array.from(e.entries()),s.previousSize=e.size}t(s);const l=e[o].apply(e,n),c={method:o,result:l,args:n,context:s,target:e,...a};return r(c),l};for(const e of n)o.includes(e)&&(s[e]=createWrappedMethod(e));return Object.defineProperty(s,"target",{get:()=>e,enumerable:!1,configurable:!1}),s},getUniqueId:(e={})=>{const t=e.prefix,r=e.suffix,o=e.base10,n=e.base36;return`${t?t+"-":""}${Date.now()}${n?"-"+Math.random().toString(36).substring(2,11):""}${o?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},deepEqual:e.deepEqual,deepMerge:(e,t,r={})=>{let o=Object.assign({itemMode:"merge",propAppend:!0,targetClone:!1,useEnable:!0},r);return deepMergeHelper(e,t,o)},deepMergeArrays:deepMergeArrays,deepMergeMaps:deepMergeMaps,deepMergeObjects:deepMergeObjects,deepMergeSets:deepMergeSets}});
|
package/dist.zip
CHANGED
|
Binary file
|
package/modules.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Last modified: 2025/12/
|
|
2
|
+
* Last modified: 2025/12/24 17:05:40
|
|
3
3
|
*/
|
|
4
4
|
'use strict';
|
|
5
5
|
import deepClone from './src/deepClone';
|
|
@@ -13,6 +13,12 @@ import setMutableMethods from './src/setMutableMethods';
|
|
|
13
13
|
import mapMutableMethods from './src/mapMutableMethods';
|
|
14
14
|
import wrapSetMethods from './src/wrapSetMethods';
|
|
15
15
|
import wrapMapMethods from './src/wrapMapMethods';
|
|
16
|
+
import { deepEqual } from 'assert';
|
|
17
|
+
import deepMerge from './src/deepMerge';
|
|
18
|
+
import deepMergeArrays from './src/deepMergeArrays';
|
|
19
|
+
import deepMergeMaps from './src/deepMergeMaps';
|
|
20
|
+
import deepMergeObjects from './src/deepMergeObjects';
|
|
21
|
+
import deepMergeSets from './src/deepMergeSets';
|
|
16
22
|
const utils = {
|
|
17
23
|
//executeStr,
|
|
18
24
|
getDataType,
|
|
@@ -27,6 +33,12 @@ const utils = {
|
|
|
27
33
|
mapMutableMethods,
|
|
28
34
|
wrapSetMethods,
|
|
29
35
|
wrapMapMethods,
|
|
30
|
-
getUniqueId
|
|
36
|
+
getUniqueId,
|
|
37
|
+
deepEqual,
|
|
38
|
+
deepMerge,
|
|
39
|
+
deepMergeArrays,
|
|
40
|
+
deepMergeMaps,
|
|
41
|
+
deepMergeObjects,
|
|
42
|
+
deepMergeSets,
|
|
31
43
|
};
|
|
32
44
|
export default utils;
|
package/modules.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Last modified: 2025/12/
|
|
2
|
+
* Last modified: 2025/12/24 17:05:40
|
|
3
3
|
*/
|
|
4
4
|
'use strict'
|
|
5
5
|
import deepClone from './src/deepClone';
|
|
@@ -16,6 +16,12 @@ import setMutableMethods from './src/setMutableMethods';
|
|
|
16
16
|
import mapMutableMethods from './src/mapMutableMethods';
|
|
17
17
|
import wrapSetMethods from './src/wrapSetMethods';
|
|
18
18
|
import wrapMapMethods from './src/wrapMapMethods';
|
|
19
|
+
import { deepEqual } from 'assert';
|
|
20
|
+
import deepMerge from './src/deepMerge';
|
|
21
|
+
import deepMergeArrays from './src/deepMergeArrays';
|
|
22
|
+
import deepMergeMaps from './src/deepMergeMaps';
|
|
23
|
+
import deepMergeObjects from './src/deepMergeObjects';
|
|
24
|
+
import deepMergeSets from './src/deepMergeSets';
|
|
19
25
|
|
|
20
26
|
|
|
21
27
|
|
|
@@ -33,7 +39,13 @@ const utils = {
|
|
|
33
39
|
mapMutableMethods,
|
|
34
40
|
wrapSetMethods,
|
|
35
41
|
wrapMapMethods,
|
|
36
|
-
getUniqueId
|
|
42
|
+
getUniqueId,
|
|
43
|
+
deepEqual,
|
|
44
|
+
deepMerge,
|
|
45
|
+
deepMergeArrays,
|
|
46
|
+
deepMergeMaps,
|
|
47
|
+
deepMergeObjects,
|
|
48
|
+
deepMergeSets,
|
|
37
49
|
};
|
|
38
50
|
|
|
39
51
|
export default utils;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codady/utils",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"author": "AXUI Development Team",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.",
|
package/src/deepClone.js
CHANGED
package/src/deepClone.ts
CHANGED
package/src/deepEqual.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/24 17:11:15
|
|
3
|
+
* @function deepEqual
|
|
4
|
+
* @description Compares two values for deep equality. This function checks whether the values are deeply equal, meaning that if the values are objects or arrays, their properties or items are recursively compared. If they are primitive types, a direct comparison is performed.
|
|
5
|
+
* It supports comparison for arrays, objects, and primitive types (like numbers, strings, booleans, etc.). The comparison is done by value, not by reference.
|
|
6
|
+
*
|
|
7
|
+
* @param a The first value to compare.
|
|
8
|
+
* @param b The second value to compare.
|
|
9
|
+
* @returns {boolean} `true` if the values are deeply equal, otherwise `false`.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* deepEqual([1, 2, 3], [1, 2, 3]); // returns true
|
|
13
|
+
* deepEqual([1, 2, 3], [3, 2, 1]); // returns false
|
|
14
|
+
* deepEqual({ a: 1, b: 2 }, { a: 1, b: 2 }); // returns true
|
|
15
|
+
* deepEqual({ a: 1, b: 2 }, { a: 1, b: 3 }); // returns false
|
|
16
|
+
* deepEqual(5, 5); // returns true
|
|
17
|
+
* deepEqual('hello', 'hello'); // returns true
|
|
18
|
+
* deepEqual(5, '5'); // returns false
|
|
19
|
+
*/
|
|
20
|
+
const deepEqual = (a, b) => {
|
|
21
|
+
// If both are equal by reference
|
|
22
|
+
if (a === b)
|
|
23
|
+
return true;
|
|
24
|
+
// If both are arrays, check equality recursively
|
|
25
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
26
|
+
if (a.length !== b.length)
|
|
27
|
+
return false;
|
|
28
|
+
for (let i = 0; i < a.length; i++) {
|
|
29
|
+
if (!deepEqual(a[i], b[i]))
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
// If both are objects, check equality recursively
|
|
35
|
+
if (typeof a === 'object' && typeof b === 'object') {
|
|
36
|
+
const keysA = Object.keys(a), keysB = Object.keys(b);
|
|
37
|
+
if (keysA.length !== keysB.length)
|
|
38
|
+
return false;
|
|
39
|
+
for (let key of keysA) {
|
|
40
|
+
if (!keysB.includes(key) || !deepEqual(a[key], b[key]))
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
// For other types, direct comparison
|
|
46
|
+
return a === b;
|
|
47
|
+
};
|
|
48
|
+
export default deepEqual;
|
package/src/deepEqual.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/24 17:11:15
|
|
3
|
+
* @function deepEqual
|
|
4
|
+
* @description Compares two values for deep equality. This function checks whether the values are deeply equal, meaning that if the values are objects or arrays, their properties or items are recursively compared. If they are primitive types, a direct comparison is performed.
|
|
5
|
+
* It supports comparison for arrays, objects, and primitive types (like numbers, strings, booleans, etc.). The comparison is done by value, not by reference.
|
|
6
|
+
*
|
|
7
|
+
* @param a The first value to compare.
|
|
8
|
+
* @param b The second value to compare.
|
|
9
|
+
* @returns {boolean} `true` if the values are deeply equal, otherwise `false`.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* deepEqual([1, 2, 3], [1, 2, 3]); // returns true
|
|
13
|
+
* deepEqual([1, 2, 3], [3, 2, 1]); // returns false
|
|
14
|
+
* deepEqual({ a: 1, b: 2 }, { a: 1, b: 2 }); // returns true
|
|
15
|
+
* deepEqual({ a: 1, b: 2 }, { a: 1, b: 3 }); // returns false
|
|
16
|
+
* deepEqual(5, 5); // returns true
|
|
17
|
+
* deepEqual('hello', 'hello'); // returns true
|
|
18
|
+
* deepEqual(5, '5'); // returns false
|
|
19
|
+
*/
|
|
20
|
+
const deepEqual = (a: any, b: any): boolean => {
|
|
21
|
+
// If both are equal by reference
|
|
22
|
+
if (a === b) return true;
|
|
23
|
+
|
|
24
|
+
// If both are arrays, check equality recursively
|
|
25
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
26
|
+
if (a.length !== b.length) return false;
|
|
27
|
+
for (let i = 0; i < a.length; i++) {
|
|
28
|
+
if (!deepEqual(a[i], b[i])) return false;
|
|
29
|
+
}
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// If both are objects, check equality recursively
|
|
34
|
+
if (typeof a === 'object' && typeof b === 'object') {
|
|
35
|
+
const keysA = Object.keys(a), keysB = Object.keys(b);
|
|
36
|
+
if (keysA.length !== keysB.length) return false;
|
|
37
|
+
for (let key of keysA) {
|
|
38
|
+
if (!keysB.includes(key) || !deepEqual(a[key], b[key])) return false;
|
|
39
|
+
}
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// For other types, direct comparison
|
|
44
|
+
return a === b;
|
|
45
|
+
}
|
|
46
|
+
export default deepEqual;
|
package/src/deepMerge.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/24 17:21:45
|
|
3
|
+
* @function deepMerge
|
|
4
|
+
* @description Deeply merges two data structures (Object, Array, Map, or Set) based on their types.
|
|
5
|
+
* This function recursively merges the properties or items of the target and source, depending on their types.
|
|
6
|
+
* If the types of target and source do not match, the target will be returned unchanged.
|
|
7
|
+
* @param target The target data structure to merge into (can be Object, Array, Map, or Set).
|
|
8
|
+
* @param source The source data structure to merge from (can be Object, Array, Map, or Set).
|
|
9
|
+
* @param opts Configuration options for merging. The default options include:
|
|
10
|
+
* - `itemMode`: Specifies the merging mode (`'merge'`, `'replace'`, or `'concat'`).
|
|
11
|
+
* - `propAppend`: Whether to append properties from the source if they do not exist in the target.
|
|
12
|
+
* - `targetClone`: Whether to clone the target before merging (if true, the target is not modified).
|
|
13
|
+
* - `useEnable`: Some special handling for specific objects that have `enable` properties.
|
|
14
|
+
* - `useSymbol`: Whether to merge symbol properties.
|
|
15
|
+
* @returns The deeply merged target data structure.
|
|
16
|
+
* @example
|
|
17
|
+
* let x = { a: 'man', b: 0, c: [] };
|
|
18
|
+
* let y = { a: 'woman', b: 2, d: 'new' };
|
|
19
|
+
* const merged = deepMerge(x, y, { itemMode: 'merge', propAppend: true });
|
|
20
|
+
* // Returns { a: 'woman', b: 2, c: [], d: 'new' }
|
|
21
|
+
*/
|
|
22
|
+
'use strict';
|
|
23
|
+
import deepMergeHelper from './deepMergeHelper';
|
|
24
|
+
const deepMerge = (target, source, opts = {}) => {
|
|
25
|
+
// Get the data types of the target and source
|
|
26
|
+
let options = Object.assign({
|
|
27
|
+
itemMode: 'merge', // Default merge mode
|
|
28
|
+
propAppend: true, // Default to appending properties from source to target
|
|
29
|
+
targetClone: false, // Do not clone target by default
|
|
30
|
+
useEnable: true // Enable special handling for objects with an `enable` property
|
|
31
|
+
}, opts);
|
|
32
|
+
return deepMergeHelper(target, source, options);
|
|
33
|
+
};
|
|
34
|
+
export default deepMerge;
|
package/src/deepMerge.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/24 17:21:45
|
|
3
|
+
* @function deepMerge
|
|
4
|
+
* @description Deeply merges two data structures (Object, Array, Map, or Set) based on their types.
|
|
5
|
+
* This function recursively merges the properties or items of the target and source, depending on their types.
|
|
6
|
+
* If the types of target and source do not match, the target will be returned unchanged.
|
|
7
|
+
* @param target The target data structure to merge into (can be Object, Array, Map, or Set).
|
|
8
|
+
* @param source The source data structure to merge from (can be Object, Array, Map, or Set).
|
|
9
|
+
* @param opts Configuration options for merging. The default options include:
|
|
10
|
+
* - `itemMode`: Specifies the merging mode (`'merge'`, `'replace'`, or `'concat'`).
|
|
11
|
+
* - `propAppend`: Whether to append properties from the source if they do not exist in the target.
|
|
12
|
+
* - `targetClone`: Whether to clone the target before merging (if true, the target is not modified).
|
|
13
|
+
* - `useEnable`: Some special handling for specific objects that have `enable` properties.
|
|
14
|
+
* - `useSymbol`: Whether to merge symbol properties.
|
|
15
|
+
* @returns The deeply merged target data structure.
|
|
16
|
+
* @example
|
|
17
|
+
* let x = { a: 'man', b: 0, c: [] };
|
|
18
|
+
* let y = { a: 'woman', b: 2, d: 'new' };
|
|
19
|
+
* const merged = deepMerge(x, y, { itemMode: 'merge', propAppend: true });
|
|
20
|
+
* // Returns { a: 'woman', b: 2, c: [], d: 'new' }
|
|
21
|
+
*/
|
|
22
|
+
'use strict';
|
|
23
|
+
import getDataType from './getDataType';
|
|
24
|
+
import deepMergeObjects from './deepMergeObjects';
|
|
25
|
+
import deepMergeArrays, { DeepMergeOptions } from './deepMergeArrays';
|
|
26
|
+
import deepMergeMaps from './deepMergeMaps';
|
|
27
|
+
import deepMergeSets from './deepMergeSets';
|
|
28
|
+
import deepMergeHelper from './deepMergeHelper';
|
|
29
|
+
const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, source: any, opts: DeepMergeOptions = {}): Object | Array<any> | Map<any, any> | Set<any> => {
|
|
30
|
+
// Get the data types of the target and source
|
|
31
|
+
let options = Object.assign({
|
|
32
|
+
itemMode: 'merge', // Default merge mode
|
|
33
|
+
propAppend: true, // Default to appending properties from source to target
|
|
34
|
+
targetClone: false, // Do not clone target by default
|
|
35
|
+
useEnable: true // Enable special handling for objects with an `enable` property
|
|
36
|
+
}, opts);
|
|
37
|
+
|
|
38
|
+
return deepMergeHelper(target,source,options);
|
|
39
|
+
}
|
|
40
|
+
export default deepMerge;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/24 17:49:40
|
|
3
|
+
* @function deepMergeArrays
|
|
4
|
+
* Deeply merges two arrays, with flexible options to replace, concatenate, or merge items.
|
|
5
|
+
* @param target The target array to merge into
|
|
6
|
+
* @param source The source array to merge from
|
|
7
|
+
* @param options Configuration options for merging
|
|
8
|
+
* @returns The deeply merged array
|
|
9
|
+
*/
|
|
10
|
+
'use strict';
|
|
11
|
+
import deepMergeHelper from './deepMergeHelper';
|
|
12
|
+
const deepMergeArrays = (target, source, options = { itemMode: 'merge', propAppend: true, targetClone: false, useEnable: true }) => {
|
|
13
|
+
// Ensure both target and source are arrays
|
|
14
|
+
if (!Array.isArray(target) || !Array.isArray(source))
|
|
15
|
+
return target;
|
|
16
|
+
// Merge options, with default values
|
|
17
|
+
const opts = Object.assign({ itemMode: 'merge', propAppend: true, targetClone: false }, options),
|
|
18
|
+
// If cloning is enabled, create a deep copy of the target array
|
|
19
|
+
result = opts.targetClone ? [...target] : target;
|
|
20
|
+
// Handle different merge strategies based on itemMode
|
|
21
|
+
if (opts.itemMode === 'replace') {
|
|
22
|
+
// Replace mode: clear the target array and push all items from the source array
|
|
23
|
+
result.length = 0;
|
|
24
|
+
result.push(...source);
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
else if (opts.itemMode === 'concat') {
|
|
28
|
+
// Concatenate mode: append all items from the source array to the target array
|
|
29
|
+
result.push(...source);
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
// Default "merge" mode: recursively merge items in the arrays
|
|
34
|
+
for (let i = 0; i < source.length; i++) {
|
|
35
|
+
let resp = deepMergeHelper(result[i], source[i], opts);
|
|
36
|
+
//resp={result,flag,type}
|
|
37
|
+
//flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
|
|
38
|
+
if (!resp.flag) {
|
|
39
|
+
result[i] = source[i];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
export default deepMergeArrays;
|