@codady/utils 0.0.10 → 0.0.12
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 +37 -0
- package/dist/utils.cjs.js +274 -3
- package/dist/utils.cjs.min.js +3 -3
- package/dist/utils.esm.js +274 -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 +274 -3
- package/dist/utils.umd.min.js +3 -3
- package/dist.zip +0 -0
- package/examples/deepMerge.html +1049 -0
- package/modules.js +6 -2
- package/modules.ts +12 -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 +274 -0
- package/src/deepMerge.ts +328 -0
- package/src/deepMergeArrays.js +45 -0
- package/src/deepMergeArrays.ts +62 -0
- package/src/deepMergeHelper.js +38 -0
- package/src/deepMergeHelper.ts +43 -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 +89 -0
- package/src/deepMergeObjects.ts +91 -0
- package/src/deepMergeSets.js +43 -0
- package/src/deepMergeSets.ts +52 -0
- package/src/mapMutableMethods - /345/211/257/346/234/254.js" +5 -0
- package/src/shallowCopy.js +46 -0
- package/src/shallowCopy.ts +55 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/25 08:22:06
|
|
3
|
+
* @function deepMergeMaps
|
|
4
|
+
* Deeply merges two Maps, with flexible options to replace, concatenate, or merge entries.
|
|
5
|
+
* @param target The target Map to merge into
|
|
6
|
+
* @param source The source Map to merge from
|
|
7
|
+
* @param options Configuration options for merging
|
|
8
|
+
* @returns The deeply merged Map
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
import getDataType from './getDataType';
|
|
14
|
+
import deepMergeObjects from './deepMergeObjects';
|
|
15
|
+
import deepMergeArrays, { DeepMergeOptions } from './deepMergeArrays';
|
|
16
|
+
import deepMergeSets from './deepMergeSets';
|
|
17
|
+
import deepEqual from './deepEqual';
|
|
18
|
+
import deepMergeHelper from './deepMergeHelper';
|
|
19
|
+
|
|
20
|
+
const deepMergeMaps = (target: Map<any, any>, source: Map<any, any>, options: DeepMergeOptions = { itemMode: 'merge', propAppend: true, targetClone: false, useEnable: true }): Map<any, any> => {
|
|
21
|
+
// Ensure both target and source are Maps
|
|
22
|
+
if (!(target instanceof Map) || !(source instanceof Map)) return target;
|
|
23
|
+
|
|
24
|
+
// Merge options, with default values
|
|
25
|
+
const opts = Object.assign({ itemMode: 'merge', propAppend: true, targetClone: false, useEnable: true }, options),
|
|
26
|
+
|
|
27
|
+
// If cloning is enabled, create a deep copy of the target Map
|
|
28
|
+
result = opts.targetClone ? new Map(target) : target;
|
|
29
|
+
|
|
30
|
+
// Handle different merge strategies based on itemMode
|
|
31
|
+
if (opts.itemMode === 'replace') {
|
|
32
|
+
// Replace mode: clear the target Map and add all entries from the source Map
|
|
33
|
+
result.clear();
|
|
34
|
+
source.forEach((value, key) => result.set(key, value));
|
|
35
|
+
return result;
|
|
36
|
+
} else if (opts.itemMode === 'concat') {
|
|
37
|
+
// Concatenate mode: add all entries from the source Map to the target Map
|
|
38
|
+
source.forEach((value, key) => result.set(key, value));
|
|
39
|
+
return result;
|
|
40
|
+
} else {
|
|
41
|
+
// Default "merge" mode: recursively merge entries in the Maps
|
|
42
|
+
source.forEach((value, key) => {
|
|
43
|
+
// Check if the key already exists in the target Map
|
|
44
|
+
if (result.has(key)) {
|
|
45
|
+
const _target = result.get(key),
|
|
46
|
+
_source = value,
|
|
47
|
+
resp = deepMergeHelper(_target, _source, opts);
|
|
48
|
+
//resp={result,flag,type}
|
|
49
|
+
//flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
|
|
50
|
+
if (!resp.flag) {
|
|
51
|
+
// For simple values, overwrite the target value with the source value
|
|
52
|
+
result.set(key, _source);
|
|
53
|
+
} else {
|
|
54
|
+
// If both target and source are objects, merge them recursively
|
|
55
|
+
resp.type === 'Object' && result.set(key, resp.result);
|
|
56
|
+
}
|
|
57
|
+
} else {
|
|
58
|
+
// If the key doesn't exist in the target, add the entry from the source Map
|
|
59
|
+
options.propAppend && result.set(key, value);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export default deepMergeMaps;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/25 08:21:18
|
|
3
|
+
* @function deepMergeObjects
|
|
4
|
+
* @description Merge two objects. The key name of Source is allowed to be the Symbol type, and the Symbol key name of the source will be added directly to the target.
|
|
5
|
+
* @param {Object} target - The original target of the merge.
|
|
6
|
+
* @param {Object} source - The object that will merge into the target.
|
|
7
|
+
* @param {DeepMergeOptions} [opts] - Parameters used for merging objects.
|
|
8
|
+
* @param {boolean} [opts.arrAppend=false] - If value is an array, whether to append or override.
|
|
9
|
+
* @param {boolean} [opts.propAppend=true] - Whether to append properties from source to target if not already present.
|
|
10
|
+
* @param {boolean} [opts.targetClone=false] - Whether to clone the target object, if true, the original target will not be changed.
|
|
11
|
+
* @param {boolean} [opts.useEnable=true] - Whether to merge enable property.
|
|
12
|
+
* @param {boolean} [opts.useSymbol=true] - Whether to merge symbol properties.
|
|
13
|
+
* @returns {Object} - The merged object.
|
|
14
|
+
* @example
|
|
15
|
+
* let x ={a:'man',b:0,c:[]}, b={a:'woman',b:2};
|
|
16
|
+
* deepMergeObjects(x, b);
|
|
17
|
+
* // Returns {a:'woman', b:2, c:[]}
|
|
18
|
+
*/
|
|
19
|
+
'use strict';
|
|
20
|
+
import getDataType from './getDataType';
|
|
21
|
+
import deepClone from './deepClone';
|
|
22
|
+
import deepMergeHelper from './deepMergeHelper';
|
|
23
|
+
const deepMergeObjects = (target, source, opts = {}) => {
|
|
24
|
+
let targetType = getDataType(target), sourceType = getDataType(source);
|
|
25
|
+
//target不是对象或者source为空则直接返回
|
|
26
|
+
if (targetType !== 'Object' || sourceType !== 'Object') {
|
|
27
|
+
return target;
|
|
28
|
+
}
|
|
29
|
+
const options = Object.assign({ itemMode: 'merge', propAppend: true, targetClone: false, useEnable: true }, opts),
|
|
30
|
+
//如果是复制方法,则先复制target
|
|
31
|
+
result = options.targetClone ? deepClone(target) : target;
|
|
32
|
+
for (let k in source) {
|
|
33
|
+
if (source.hasOwnProperty(k) && result.hasOwnProperty(k)) {
|
|
34
|
+
let resp = deepMergeHelper(result[k], source[k], opts);
|
|
35
|
+
//resp={result,flag,type}
|
|
36
|
+
//flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
|
|
37
|
+
if (!resp.flag) {
|
|
38
|
+
//类型不同则直接覆盖
|
|
39
|
+
if (options.useEnable && result.hasOwnProperty(k) && result[k]?.hasOwnProperty('enable') && typeof source[k] === 'boolean') {
|
|
40
|
+
//部分替换,仅针对result={enable:true/false,a:''},source=false/true这种情况和相反的情况,因为这种情况再笨框架比较多见
|
|
41
|
+
if (result[k]?.hasOwnProperty('enable') && typeof source[k] === 'boolean') {
|
|
42
|
+
//result={enable:true,a:'',b:''},source[k]=false=>result={enable:false,a:'',b:''}
|
|
43
|
+
result[k].enable = source[k];
|
|
44
|
+
}
|
|
45
|
+
else if (source[k]?.hasOwnProperty('enable') && typeof result[k] === 'boolean') {
|
|
46
|
+
//source={enable:true,a:'',b:''},(result as any)[k]=false=>result={enable:false,a:'',b:''}
|
|
47
|
+
result = Object.assign({ enable: result[k] }, source[k]);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
//完全替换
|
|
51
|
+
result[k] = source[k];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
//完全替换
|
|
56
|
+
result[k] = source[k];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
//类型相同
|
|
61
|
+
if (resp.type) {
|
|
62
|
+
if (resp.type === 'Object') {
|
|
63
|
+
//如果遇上对象则深度复制
|
|
64
|
+
result[k] = resp.result;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
//其他清空则直接覆盖
|
|
69
|
+
result[k] = source[k];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else if (source.hasOwnProperty(k) && !result.hasOwnProperty(k) && options.propAppend) {
|
|
74
|
+
//如果source有属性,result没有该属性,但是options允许追加属性则直接赋值
|
|
75
|
+
result[k] = source[k];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//Symbol键直接追加,因为Symbol是唯一,结果同Object.assign
|
|
79
|
+
if (options.useSymbol) {
|
|
80
|
+
let symbols = Object.getOwnPropertySymbols(source);
|
|
81
|
+
if (symbols.length > 0) {
|
|
82
|
+
for (let k of symbols) {
|
|
83
|
+
result[k] = source[k];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
};
|
|
89
|
+
export default deepMergeObjects;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/25 08:21:18
|
|
3
|
+
* @function deepMergeObjects
|
|
4
|
+
* @description Merge two objects. The key name of Source is allowed to be the Symbol type, and the Symbol key name of the source will be added directly to the target.
|
|
5
|
+
* @param {Object} target - The original target of the merge.
|
|
6
|
+
* @param {Object} source - The object that will merge into the target.
|
|
7
|
+
* @param {DeepMergeOptions} [opts] - Parameters used for merging objects.
|
|
8
|
+
* @param {boolean} [opts.arrAppend=false] - If value is an array, whether to append or override.
|
|
9
|
+
* @param {boolean} [opts.propAppend=true] - Whether to append properties from source to target if not already present.
|
|
10
|
+
* @param {boolean} [opts.targetClone=false] - Whether to clone the target object, if true, the original target will not be changed.
|
|
11
|
+
* @param {boolean} [opts.useEnable=true] - Whether to merge enable property.
|
|
12
|
+
* @param {boolean} [opts.useSymbol=true] - Whether to merge symbol properties.
|
|
13
|
+
* @returns {Object} - The merged object.
|
|
14
|
+
* @example
|
|
15
|
+
* let x ={a:'man',b:0,c:[]}, b={a:'woman',b:2};
|
|
16
|
+
* deepMergeObjects(x, b);
|
|
17
|
+
* // Returns {a:'woman', b:2, c:[]}
|
|
18
|
+
*/
|
|
19
|
+
'use strict';
|
|
20
|
+
import getDataType from './getDataType';
|
|
21
|
+
import deepClone from './deepClone';
|
|
22
|
+
import deepMergeArrays, { DeepMergeOptions } from './deepMergeArrays';
|
|
23
|
+
import deepMergeSets from './deepMergeSets';
|
|
24
|
+
import deepMergeMaps from './deepMergeMaps';
|
|
25
|
+
import deepMergeHelper from './deepMergeHelper';
|
|
26
|
+
const deepMergeObjects = (target: Object, source: any, opts: DeepMergeOptions = {}): Object => {
|
|
27
|
+
let targetType = getDataType(target),
|
|
28
|
+
sourceType = getDataType(source);
|
|
29
|
+
//target不是对象或者source为空则直接返回
|
|
30
|
+
if (targetType !== 'Object' || sourceType !== 'Object') {
|
|
31
|
+
return target;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const options = Object.assign({ itemMode: 'merge', propAppend: true, targetClone: false, useEnable: true }, opts),
|
|
35
|
+
//如果是复制方法,则先复制target
|
|
36
|
+
result = options.targetClone ? deepClone(target) : target;
|
|
37
|
+
|
|
38
|
+
for (let k in source) {
|
|
39
|
+
if (source.hasOwnProperty(k) && result.hasOwnProperty(k)) {
|
|
40
|
+
|
|
41
|
+
let resp = deepMergeHelper((result as any)[k], source[k], opts);
|
|
42
|
+
//resp={result,flag,type}
|
|
43
|
+
//flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
|
|
44
|
+
if (!resp.flag) {
|
|
45
|
+
//类型不同则直接覆盖
|
|
46
|
+
if (options.useEnable && result.hasOwnProperty(k) && (result as any)[k]?.hasOwnProperty('enable') && typeof source[k] === 'boolean') {
|
|
47
|
+
//部分替换,仅针对result={enable:true/false,a:''},source=false/true这种情况和相反的情况,因为这种情况再笨框架比较多见
|
|
48
|
+
if ((result as any)[k]?.hasOwnProperty('enable') && typeof source[k] === 'boolean') {
|
|
49
|
+
//result={enable:true,a:'',b:''},source[k]=false=>result={enable:false,a:'',b:''}
|
|
50
|
+
(result as any)[k].enable = source[k];
|
|
51
|
+
} else if (source[k]?.hasOwnProperty('enable') && typeof (result as any)[k] === 'boolean') {
|
|
52
|
+
//source={enable:true,a:'',b:''},(result as any)[k]=false=>result={enable:false,a:'',b:''}
|
|
53
|
+
(result as any) = Object.assign({ enable: (result as any)[k] }, source[k]);
|
|
54
|
+
} else {
|
|
55
|
+
//完全替换
|
|
56
|
+
(result as any)[k] = source[k];
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
//完全替换
|
|
60
|
+
(result as any)[k] = source[k];
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
//类型相同
|
|
64
|
+
if (resp.type) {
|
|
65
|
+
if (resp.type === 'Object') {
|
|
66
|
+
//如果遇上对象则深度复制
|
|
67
|
+
(result as any)[k] = resp.result;
|
|
68
|
+
}
|
|
69
|
+
} else {
|
|
70
|
+
//其他清空则直接覆盖
|
|
71
|
+
(result as any)[k] = source[k];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
} else if (source.hasOwnProperty(k) && !result.hasOwnProperty(k) && options.propAppend) {
|
|
76
|
+
//如果source有属性,result没有该属性,但是options允许追加属性则直接赋值
|
|
77
|
+
(result as any)[k] = source[k];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//Symbol键直接追加,因为Symbol是唯一,结果同Object.assign
|
|
81
|
+
if (options.useSymbol) {
|
|
82
|
+
let symbols = Object.getOwnPropertySymbols(source);
|
|
83
|
+
if (symbols.length > 0) {
|
|
84
|
+
for (let k of symbols) {
|
|
85
|
+
(result as any)[k] = source[k];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
export default deepMergeObjects;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/25 08:10:14
|
|
3
|
+
* @function deepMergeSets
|
|
4
|
+
* Deeply merges two Sets, with flexible options to replace, concatenate, or merge items.
|
|
5
|
+
* @param target The target Set to merge into
|
|
6
|
+
* @param source The source Set to merge from
|
|
7
|
+
* @param options Configuration options for merging
|
|
8
|
+
* @returns The deeply merged Set
|
|
9
|
+
*/
|
|
10
|
+
'use strict';
|
|
11
|
+
import deepMergeHelper from './deepMergeHelper';
|
|
12
|
+
const deepMergeSets = (target, source, options = { itemMode: 'merge', propAppend: true, targetClone: false, useEnable: true }) => {
|
|
13
|
+
// Ensure both target and source are Sets
|
|
14
|
+
if (!(target instanceof Set) || !(source instanceof Set))
|
|
15
|
+
return target;
|
|
16
|
+
// Merge options, with default values
|
|
17
|
+
const opts = Object.assign({ itemMode: 'merge', propAppend: true, targetClone: false, useEnable: true }, options),
|
|
18
|
+
// If cloning is enabled, create a deep copy of the target Set
|
|
19
|
+
result = opts.targetClone ? new Set(target) : target;
|
|
20
|
+
// Handle different merge strategies based on itemMode
|
|
21
|
+
if (opts.itemMode === 'replace') {
|
|
22
|
+
// Replace mode: clear the target Set and add all items from the source Set
|
|
23
|
+
result.clear();
|
|
24
|
+
for (let item of source)
|
|
25
|
+
result.add(item);
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
else if (opts.itemMode === 'concat') {
|
|
29
|
+
// Concatenate mode: add all items from the source Set to the target Set
|
|
30
|
+
for (let item of source)
|
|
31
|
+
result.add(item);
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
// Default "merge" mode: recursively merge items in the Sets
|
|
36
|
+
const _result = [...result], _source = [...source], resp = deepMergeHelper(_result, _source, opts);
|
|
37
|
+
result.clear();
|
|
38
|
+
for (let item of resp.result)
|
|
39
|
+
result.add(item);
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
export default deepMergeSets;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/25 08:10:14
|
|
3
|
+
* @function deepMergeSets
|
|
4
|
+
* Deeply merges two Sets, with flexible options to replace, concatenate, or merge items.
|
|
5
|
+
* @param target The target Set to merge into
|
|
6
|
+
* @param source The source Set to merge from
|
|
7
|
+
* @param options Configuration options for merging
|
|
8
|
+
* @returns The deeply merged Set
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
import getDataType from './getDataType';
|
|
14
|
+
import deepMergeObjects from './deepMergeObjects';
|
|
15
|
+
import deepMergeArrays, { DeepMergeOptions } from './deepMergeArrays';
|
|
16
|
+
import deepEqual from './deepEqual';
|
|
17
|
+
import deepMergeMaps from './deepMergeMaps';
|
|
18
|
+
import deepMergeHelper from './deepMergeHelper';
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
const deepMergeSets = (target: Set<any>, source: Set<any>, options: DeepMergeOptions = { itemMode: 'merge', propAppend: true, targetClone: false, useEnable: true }): Set<any> => {
|
|
22
|
+
// Ensure both target and source are Sets
|
|
23
|
+
if (!(target instanceof Set) || !(source instanceof Set)) return target;
|
|
24
|
+
|
|
25
|
+
// Merge options, with default values
|
|
26
|
+
const opts = Object.assign({ itemMode: 'merge', propAppend: true, targetClone: false, useEnable: true }, options),
|
|
27
|
+
|
|
28
|
+
// If cloning is enabled, create a deep copy of the target Set
|
|
29
|
+
result = opts.targetClone ? new Set(target) : target;
|
|
30
|
+
|
|
31
|
+
// Handle different merge strategies based on itemMode
|
|
32
|
+
if (opts.itemMode === 'replace') {
|
|
33
|
+
// Replace mode: clear the target Set and add all items from the source Set
|
|
34
|
+
result.clear();
|
|
35
|
+
for (let item of source) result.add(item);
|
|
36
|
+
return result;
|
|
37
|
+
} else if (opts.itemMode === 'concat') {
|
|
38
|
+
// Concatenate mode: add all items from the source Set to the target Set
|
|
39
|
+
for (let item of source) result.add(item);
|
|
40
|
+
return result;
|
|
41
|
+
} else {
|
|
42
|
+
// Default "merge" mode: recursively merge items in the Sets
|
|
43
|
+
const _result = [...result],
|
|
44
|
+
_source = [...source],
|
|
45
|
+
resp = deepMergeHelper(_result, _source, opts);
|
|
46
|
+
result.clear();
|
|
47
|
+
for (let item of resp.result) result.add(item);
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default deepMergeSets;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/25 12:07:26
|
|
3
|
+
* shallowCopy
|
|
4
|
+
*
|
|
5
|
+
* This function performs a shallow copy of various data structures:
|
|
6
|
+
* - Set
|
|
7
|
+
* - Map
|
|
8
|
+
* - Array
|
|
9
|
+
* - Plain Object (including properties with Symbol keys)
|
|
10
|
+
*
|
|
11
|
+
* It returns a new instance of the data structure, but the elements or properties of reference types (such as objects or arrays) will be copied by reference.
|
|
12
|
+
* Primitive types (e.g., number, string, boolean) will be returned directly.
|
|
13
|
+
*/
|
|
14
|
+
'use strict';
|
|
15
|
+
import getDataType from "./getDataType";
|
|
16
|
+
const shallowCopy = (data) => {
|
|
17
|
+
const dataType = getDataType(data);
|
|
18
|
+
// Check if data is a Set
|
|
19
|
+
if (dataType === 'Set') {
|
|
20
|
+
// Shallow copy Set
|
|
21
|
+
return new Set([...data]);
|
|
22
|
+
}
|
|
23
|
+
// Check if data is a Map
|
|
24
|
+
if (dataType === 'Map') {
|
|
25
|
+
// Shallow copy Map
|
|
26
|
+
return new Map([...data]);
|
|
27
|
+
}
|
|
28
|
+
// Check if data is an Array
|
|
29
|
+
if (Array.isArray(data)) {
|
|
30
|
+
// Shallow copy Array
|
|
31
|
+
return [...data];
|
|
32
|
+
}
|
|
33
|
+
// Check if data is a Plain Object (including Symbol keys)
|
|
34
|
+
if (dataType === 'object') {
|
|
35
|
+
const obj = data; // Ensure the object type includes string and symbol keys
|
|
36
|
+
const symbolProperties = Object.getOwnPropertySymbols(obj).reduce((acc, sym) => {
|
|
37
|
+
acc[sym] = obj[sym];
|
|
38
|
+
return acc;
|
|
39
|
+
}, {});
|
|
40
|
+
// Shallow copy the object and include the Symbol properties
|
|
41
|
+
return { ...obj, ...symbolProperties };
|
|
42
|
+
}
|
|
43
|
+
// For other types (such as numbers, strings, booleans, etc.), return the original value
|
|
44
|
+
return data;
|
|
45
|
+
};
|
|
46
|
+
export default shallowCopy;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/25 12:07:26
|
|
3
|
+
* shallowCopy
|
|
4
|
+
*
|
|
5
|
+
* This function performs a shallow copy of various data structures:
|
|
6
|
+
* - Set
|
|
7
|
+
* - Map
|
|
8
|
+
* - Array
|
|
9
|
+
* - Plain Object (including properties with Symbol keys)
|
|
10
|
+
*
|
|
11
|
+
* It returns a new instance of the data structure, but the elements or properties of reference types (such as objects or arrays) will be copied by reference.
|
|
12
|
+
* Primitive types (e.g., number, string, boolean) will be returned directly.
|
|
13
|
+
*/
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
import getDataType from "./getDataType";
|
|
17
|
+
|
|
18
|
+
const shallowCopy = (data: any): any => {
|
|
19
|
+
const dataType = getDataType(data);
|
|
20
|
+
|
|
21
|
+
// Check if data is a Set
|
|
22
|
+
if (dataType === 'Set') {
|
|
23
|
+
// Shallow copy Set
|
|
24
|
+
return new Set([...data]);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Check if data is a Map
|
|
28
|
+
if (dataType === 'Map') {
|
|
29
|
+
// Shallow copy Map
|
|
30
|
+
return new Map([...data]);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Check if data is an Array
|
|
34
|
+
if (Array.isArray(data)) {
|
|
35
|
+
// Shallow copy Array
|
|
36
|
+
return [...data];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Check if data is a Plain Object (including Symbol keys)
|
|
40
|
+
if (dataType === 'object') {
|
|
41
|
+
const obj = data as { [key: string | symbol]: any }; // Ensure the object type includes string and symbol keys
|
|
42
|
+
const symbolProperties = Object.getOwnPropertySymbols(obj).reduce((acc: { [key: symbol]: any }, sym: symbol) => {
|
|
43
|
+
acc[sym] = obj[sym];
|
|
44
|
+
return acc;
|
|
45
|
+
}, {});
|
|
46
|
+
|
|
47
|
+
// Shallow copy the object and include the Symbol properties
|
|
48
|
+
return { ...obj, ...symbolProperties };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// For other types (such as numbers, strings, booleans, etc.), return the original value
|
|
52
|
+
return data;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export default shallowCopy;
|