ph-utils 0.17.2 → 0.19.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Tenny
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/lib/dom.d.ts CHANGED
@@ -7,9 +7,21 @@
7
7
  * 根据选择器获取节点
8
8
  * @param {string} selector 选择器
9
9
  */
10
- type FormatStyleParam = (string | undefined | null)[] | Record<string, boolean | string | undefined | null> | string;
11
- type FormatClassParam = (string | undefined | null | boolean)[] | Record<string, boolean | string | undefined | null | boolean> | string;
10
+ type FormatStyleParam =
11
+ | (string | undefined | null)[]
12
+ | Record<string, boolean | string | undefined | null>
13
+ | string;
14
+ type FormatClassParam =
15
+ | (string | undefined | null | boolean)[]
16
+ | Record<string, boolean | string | undefined | null | boolean>
17
+ | string;
12
18
  type DocumentContext = HTMLElement | ShadowRoot | Document;
19
+ type NodeChildren =
20
+ | HTMLElement
21
+ | DocumentFragment
22
+ | HTMLElement[]
23
+ | NodeListOf<HTMLElement>
24
+ | HTMLCollection;
13
25
  export declare function elem(selector: string | HTMLElement, dom?: DocumentContext): HTMLElement[];
14
26
  /**
15
27
  * 根据选择器获取 DOM 元素。
@@ -22,33 +34,44 @@ export declare function $(selector: string | HTMLElement, dom?: DocumentContext)
22
34
  * 创建一个 HTML 元素,支持通过标签名或 HTML 字符串创建。
23
35
  * @param tag - 元素标签名或 HTML 字符串。
24
36
  * @param option - 元素的属性、样式、文本内容等配置。所有不是指定的属性,都会通过 setAttribute 设置
25
- * @param ctx - 元素的父级文档上下文。
37
+ * @param children - 子节点
26
38
  * @returns 创建的 HTML 元素。
27
39
  */
28
- export declare function create(tag: string, option?: {
40
+ export declare function create(
41
+ tag: string,
42
+ option?: {
29
43
  class?: FormatClassParam;
30
44
  style?: FormatStyleParam;
31
45
  textContent?: string;
32
46
  innerHTML?: string;
33
47
  outerHTML?: string;
34
48
  [index: string]: any;
35
- }, ctx?: DocumentContext): HTMLElement;
49
+ },
50
+ children?: NodeChildren,
51
+ ): HTMLElement;
36
52
  /** 创建节点 */
37
- export declare function $$(tag: string, option?: {
53
+ export declare function $$(
54
+ tag: string,
55
+ option?: {
38
56
  class?: FormatClassParam;
39
57
  style?: FormatStyleParam;
40
58
  textContent?: string;
41
59
  innerHTML?: string;
42
60
  outerHTML?: string;
43
61
  [index: string]: any;
44
- }, ctx?: DocumentContext): HTMLElement;
62
+ },
63
+ children?: NodeChildren,
64
+ ): HTMLElement;
45
65
  /**
46
66
  * 根据选择器获取匹配的第一个 DOM 元素。
47
67
  * @param selector - 选择器字符串或直接的 HTMLElement。
48
68
  * @param dom - 可选的父级 DOM 元素,默认为当前文档。
49
69
  * @returns 返回匹配的第一个 HTMLElement,如果没有找到则返回 null。
50
70
  */
51
- export declare function $one(selector: string | HTMLElement, dom?: DocumentContext): HTMLElement | null;
71
+ export declare function $one(
72
+ selector: string | HTMLElement,
73
+ dom?: DocumentContext,
74
+ ): HTMLElement | null;
52
75
  /**
53
76
  * 为节点添加 class
54
77
  * @param {HTMLElement} elem 待添加 class 的节点
@@ -75,6 +98,22 @@ export declare function hasClass(elem: HTMLElement, clazz: string): boolean;
75
98
  * @param clazz - 要切换的类名。
76
99
  */
77
100
  export declare function toggleClass(el: HTMLElement, clazz: string): void;
101
+ /**
102
+ * 替换指定元素的 CSS 类
103
+ *
104
+ * 该函数用于根据给定的旧类名或类索引,将其替换为新类名。
105
+ * 如果旧类不存在,则不会进行替换。
106
+ *
107
+ * @param el - 目标 HTML 元素,将对其类进行操作
108
+ * @param oldClazz - 要替换的旧类名或类索引(基于数字时对应 classList 的索引位置)
109
+ * @param newClazz - 新的类名,用于替换旧的类
110
+ * @returns void
111
+ */
112
+ export declare function replaceClass(
113
+ el: HTMLElement,
114
+ oldClazz: string | number,
115
+ newClazz: string,
116
+ ): void;
78
117
  type EventHandler = EventListenerOrEventListenerObject | ((e: CustomEvent) => void);
79
118
  /**
80
119
  * 为节点添加事件处理
@@ -83,16 +122,40 @@ type EventHandler = EventListenerOrEventListenerObject | ((e: CustomEvent) => vo
83
122
  * @param {function} fn 事件处理函数
84
123
  * @param {boolean} option 是否是只运行一次的处理函数或者配置,其中 eventFlag 为 string,如果配置该项,则表明为委托事件
85
124
  */
86
- export declare function on(element: HTMLElement | ShadowRoot | Document | HTMLCollection | NodeListOf<HTMLElement> | HTMLElement[], listener: string, fn: EventHandler, option?: boolean | (AddEventListenerOptions & {
87
- eventFlag?: string;
88
- })): void;
125
+ export declare function on(
126
+ element:
127
+ | HTMLElement
128
+ | ShadowRoot
129
+ | Document
130
+ | HTMLCollection
131
+ | NodeListOf<HTMLElement>
132
+ | HTMLElement[],
133
+ listener: string,
134
+ fn: EventHandler,
135
+ option?:
136
+ | boolean
137
+ | (AddEventListenerOptions & {
138
+ eventFlag?: string;
139
+ }),
140
+ ): void;
89
141
  /**
90
142
  * 移除指定元素的事件监听器。
91
143
  * @param el - 要移除监听器的 HTML 元素。
92
144
  * @param listener - 事件名称。
93
145
  * @param fn - 要移除的事件监听器函数。
94
146
  */
95
- export declare function off(el: HTMLElement | ShadowRoot | Document | HTMLCollection | NodeListOf<HTMLElement> | HTMLElement[], listener: string, fn: EventHandler, option?: boolean | EventListenerOptions): void;
147
+ export declare function off(
148
+ el:
149
+ | HTMLElement
150
+ | ShadowRoot
151
+ | Document
152
+ | HTMLCollection
153
+ | NodeListOf<HTMLElement>
154
+ | HTMLElement[],
155
+ listener: string,
156
+ fn: EventHandler,
157
+ option?: boolean | EventListenerOptions,
158
+ ): void;
96
159
  /**
97
160
  * 判断事件是否应该继续传递。
98
161
  * 从事件目标开始向上遍历DOM树,检查每个节点上是否存在指定的属性。
@@ -105,7 +168,11 @@ export declare function off(el: HTMLElement | ShadowRoot | Document | HTMLCollec
105
168
  * @param endRoot - 可选,如果传递该参数,则表示停止遍历的节点,如果未传递,则表示遍历到文档根节点为止
106
169
  * @returns 包含三个元素的数组:[是否继续传递事件, 属性值, 当前检查的DOM节点]
107
170
  */
108
- export declare function shouldEventNext(e: Event, eventFlag: string, endRoot?: HTMLElement | ShadowRoot): [boolean, string, HTMLElement];
171
+ export declare function shouldEventNext(
172
+ e: Event,
173
+ eventFlag: string,
174
+ endRoot?: HTMLElement | ShadowRoot,
175
+ ): [boolean, string, HTMLElement];
109
176
  /**
110
177
  * 设置或获取节点的 innerHTML 属性
111
178
  * @param element
@@ -121,7 +188,10 @@ export declare function html(element: HTMLElement, htmlstr?: string): string | u
121
188
  */
122
189
  export declare function text(element: HTMLElement, textstr?: string): string | undefined | null;
123
190
  export declare function iterate<T>(elems: T[], fn: (el: T, index: number) => any): void;
124
- export declare function iterate(elems: NodeList | HTMLCollection | NodeListOf<HTMLElement>, fn: (el: HTMLElement, index: number) => any): void;
191
+ export declare function iterate(
192
+ elems: NodeList | HTMLCollection | NodeListOf<HTMLElement>,
193
+ fn: (el: HTMLElement, index: number) => any,
194
+ ): void;
125
195
  /**
126
196
  * 设置或获取节点 data-* 属性
127
197
  * @param elem
@@ -129,7 +199,11 @@ export declare function iterate(elems: NodeList | HTMLCollection | NodeListOf<HT
129
199
  * @param value 如果传递该值表示获取;否则表示设置
130
200
  * @returns
131
201
  */
132
- export declare function attr(elem: HTMLElement, key: string, value?: string): string | null | undefined;
202
+ export declare function attr(
203
+ elem: HTMLElement,
204
+ key: string,
205
+ value?: string,
206
+ ): string | null | undefined;
133
207
  /**
134
208
  * 获取属性值
135
209
  * @param key 属性名称
@@ -143,7 +217,11 @@ export declare function getAttr(el: HTMLElement, key: string): string;
143
217
  export declare function getAttr(el: HTMLElement, filepath: string, defaultValue: string): string;
144
218
  export declare function getAttr(el: HTMLElement, filepath: string, defaultValue: number): number;
145
219
  export declare function getAttr(el: HTMLElement, filepath: string, defaultValue: boolean): boolean;
146
- export declare function getAttr<T extends Record<string, string | number | boolean>>(el: HTMLElement, filepath: string, defaultValue: T): T;
220
+ export declare function getAttr<T extends Record<string, string | number | boolean>>(
221
+ el: HTMLElement,
222
+ filepath: string,
223
+ defaultValue: T,
224
+ ): T;
147
225
  /**
148
226
  * 获取指定节点的父节点
149
227
  * @param el
@@ -156,9 +234,12 @@ export declare function parent(el: HTMLElement): HTMLElement;
156
234
  * @param parent - 添加临时节点的父节点, 如果传递 null, 则通过修改原始样式方式计算,默认为: body.
157
235
  * @returns The DOMRect of the element.
158
236
  */
159
- export declare function queryHideNodeSize(hideNode: string | HTMLElement, parent?: null | HTMLElement): {
160
- width: number;
161
- height: number;
237
+ export declare function queryHideNodeSize(
238
+ hideNode: string | HTMLElement,
239
+ parent?: null | HTMLElement,
240
+ ): {
241
+ width: number;
242
+ height: number;
162
243
  };
163
244
  /**
164
245
  * 判断元素是否在父元素的可视区域内。
@@ -168,7 +249,11 @@ export declare function queryHideNodeSize(hideNode: string | HTMLElement, parent
168
249
  * @param direction 检查的方向,默认为"horizontal"
169
250
  * @returns 如果元素在父元素的可视区域内,则返回true;否则返回false。
170
251
  */
171
- export declare function isVisible(el: HTMLElement, parent?: HTMLElement | null | undefined, direction?: string): boolean;
252
+ export declare function isVisible(
253
+ el: HTMLElement,
254
+ parent?: HTMLElement | null | undefined,
255
+ direction?: string,
256
+ ): boolean;
172
257
  /**
173
258
  * 判断当前设备是否为移动设备。
174
259
  *
@@ -185,7 +270,12 @@ export declare function isMobile(): boolean;
185
270
  * @param classObj - 类名对象或数组
186
271
  * @returns 格式化后的类名字符串
187
272
  */
188
- export declare function formatClass(classObj: (boolean | string | undefined | null)[] | Record<string, boolean | string | undefined | null> | string): string;
273
+ export declare function formatClass(
274
+ classObj:
275
+ | (boolean | string | undefined | null)[]
276
+ | Record<string, boolean | string | undefined | null>
277
+ | string,
278
+ ): string;
189
279
  /**
190
280
  * 将样式对象格式化为 CSS 样式字符串。
191
281
  * @param styleObj - 样式对象,可以是字符串数组或键值对对象。
@@ -221,7 +311,12 @@ export declare function formatStyle(styleObj: FormatStyleParam): string;
221
311
  * @example <caption>动画结束后移除节点</caption>
222
312
  * transition($el, [["opacity", "0", "0.3s"]], "leave", () => { $el.remove(); });
223
313
  */
224
- export declare function transition(el: HTMLElement, nameOrProperties: string | [string, string, string][], dir?: "leave" | "enter", finish?: () => void): void;
314
+ export declare function transition(
315
+ el: HTMLElement,
316
+ nameOrProperties: string | [string, string, string][],
317
+ dir?: "leave" | "enter",
318
+ finish?: () => void,
319
+ ): void;
225
320
  /**
226
321
  * 计算光标位置
227
322
  *
@@ -245,8 +340,13 @@ export declare function transition(el: HTMLElement, nameOrProperties: string | [
245
340
  * // 替换字符时,保持位置
246
341
  * calcuteCursorPosition(2, 2, "abc", "axc"); // 返回 { start: 2, end: 2 }
247
342
  */
248
- export declare function calcuteCursorPosition(start: number, end: number, oldValue: string, newValue: string): {
249
- start: number;
250
- end: number;
343
+ export declare function calcuteCursorPosition(
344
+ start: number,
345
+ end: number,
346
+ oldValue: string,
347
+ newValue: string,
348
+ ): {
349
+ start: number;
350
+ end: number;
251
351
  };
252
352
  export {};
package/lib/dom.js CHANGED
@@ -22,7 +22,7 @@ export function $(selector, dom) {
22
22
  * @param ctx - 元素的父级文档上下文。
23
23
  * @returns 创建的 HTML 元素。
24
24
  */
25
- export function create(tag, option = {}, ctx) {
25
+ export function create(tag, option = {}, children) {
26
26
  let $el;
27
27
  if (tag.startsWith("<") && tag.endsWith(">")) {
28
28
  const parser = new DOMParser();
@@ -53,7 +53,7 @@ export function create(tag, option = {}, ctx) {
53
53
  $el.outerHTML = value;
54
54
  }
55
55
  else {
56
- if (value === true) {
56
+ if (typeof value === "boolean" && value === true) {
57
57
  $el.setAttribute(key, "");
58
58
  }
59
59
  else {
@@ -63,15 +63,30 @@ export function create(tag, option = {}, ctx) {
63
63
  }
64
64
  }
65
65
  }
66
- if (ctx) {
67
- ctx.appendChild($el);
66
+ if (children) {
67
+ if (children instanceof HTMLElement || children instanceof DocumentFragment) {
68
+ $el.appendChild(children);
69
+ }
70
+ else {
71
+ let len = children.length;
72
+ const fragment = document.createDocumentFragment();
73
+ for (let i = 0; i < len; i++) {
74
+ const child = children[i];
75
+ if (child instanceof HTMLElement) {
76
+ fragment.appendChild(child);
77
+ }
78
+ }
79
+ if (len > 0) {
80
+ $el.appendChild(fragment);
81
+ }
82
+ }
68
83
  }
69
84
  }
70
85
  return $el;
71
86
  }
72
87
  /** 创建节点 */
73
- export function $$(tag, option = {}, ctx) {
74
- return create(tag, option, ctx);
88
+ export function $$(tag, option = {}, children) {
89
+ return create(tag, option, children);
75
90
  }
76
91
  /**
77
92
  * 根据选择器获取匹配的第一个 DOM 元素。
@@ -124,6 +139,25 @@ export function toggleClass(el, clazz) {
124
139
  addClass(el, clazz);
125
140
  }
126
141
  }
142
+ /**
143
+ * 替换指定元素的 CSS 类
144
+ *
145
+ * 该函数用于根据给定的旧类名或类索引,将其替换为新类名。
146
+ * 如果旧类不存在,则不会进行替换。
147
+ *
148
+ * @param el - 目标 HTML 元素,将对其类进行操作
149
+ * @param oldClazz - 要替换的旧类名或类索引(基于数字时对应 classList 的索引位置)
150
+ * @param newClazz - 新的类名,用于替换旧的类
151
+ * @returns void
152
+ */
153
+ export function replaceClass(el, oldClazz, newClazz) {
154
+ // 判断 oldClazz 是否为数字,若是则通过索引从 el.classList 中获取对应类名,否则直接使用字符串值
155
+ let old = typeof oldClazz === "number" ? el.classList.item(oldClazz) : oldClazz;
156
+ // 如果旧类存在,则使用 classList.replace 方法进行替换
157
+ if (old) {
158
+ el.classList.replace(old, newClazz);
159
+ }
160
+ }
127
161
  /**
128
162
  * 为节点添加事件处理
129
163
  * @param {HTMLElement} element 添加事件的节点
@@ -0,0 +1,79 @@
1
+ /**
2
+ * 数组排序
3
+ * @param arr 待排序数组
4
+ * @param order 排序信息, asc - 升序, desc - 倒序
5
+ * @param orderKey 如果是个对象数组,按哪个字段排序
6
+ * @returns
7
+ */
8
+ export declare function order<T>(arr: T[], order?: "asc" | "desc", orderKey?: string | null): T[];
9
+ /**
10
+ * 返回一个所有集合交集的新集合
11
+ *
12
+ * 如果集合本身支持 intersection, 则调用原生 intersection 函数
13
+ *
14
+ * @param arrs
15
+ *
16
+ * @returns 新集合中的元素在传入的所有集合中同时存在
17
+ */
18
+ export declare function intersection<T>(...arrs: Set<T>[]): Set<T>;
19
+ /**
20
+ * 返回一个所有列表交集的新列表
21
+ *
22
+ * @param arrs
23
+ *
24
+ * @returns 新列表中的元素在传入的所有列表中同时存在
25
+ */
26
+ export declare function intersection<T>(...arrs: T[][]): T[];
27
+ /**
28
+ * 返回一个包含第一个集合中的元素但不包含后续给定集合中元素的新集合
29
+ *
30
+ * 如果集合本身支持 difference 方法,则调用原生 difference 方法
31
+ *
32
+ * @param arrs 集合列表
33
+ *
34
+ * @returns
35
+ */
36
+ export declare function difference<T>(...arrs: Set<T>[]): Set<T>;
37
+ /**
38
+ * 返回一个包含第一个列表中的元素但不包含后续给定列表中元素的新列表
39
+ *
40
+ * @param arrs 二维列表
41
+ *
42
+ * @returns
43
+ */
44
+ export declare function difference<T>(...arrs: T[][]): T[];
45
+ /**
46
+ * 返回多个集合的并集, 如果支持 union,则调用原生 union
47
+ *
48
+ * @param arrs
49
+ *
50
+ * @returns 一个包含所有给定集合的所有元素的新集合
51
+ */
52
+ export declare function union<T>(...arrs: Set<T>[]): Set<T>;
53
+ export declare function union<T>(...arrs: T[][]): T[];
54
+ export declare function symmetricDifference<T>(...arrs: Set<T>[]): Set<T>;
55
+ export declare function symmetricDifference<T>(...arrs: T[][]): T[];
56
+ /**
57
+ * 返回一个布尔值,指示此集合中的所有元素是否都在给定的集合中。
58
+ * @param a1
59
+ * @param a2
60
+ * @returns
61
+ */
62
+ export declare function isSubsetOf<T>(a1: T[] | Set<T>, a2: T[] | Set<T>): boolean;
63
+ /**
64
+ * 返回一个布尔值,指示给定集合中的所有元素是否都在此集合中。
65
+ * @param arr1
66
+ * @param arr2
67
+ * @returns
68
+ */
69
+ export declare function isSupersetOf<T>(arr1: T[] | Set<T>, arr2: T[] | Set<T>): boolean;
70
+ /**
71
+ * 返回一个布尔值,指示此集合是否与给定集合没有公共元素。
72
+ *
73
+ * 判断两个集合是否有交集, 也可以通过 intersection(arr1, arr2).length 判断
74
+ *
75
+ * @param arr1
76
+ * @param arr2
77
+ * @returns
78
+ */
79
+ export declare function isDisjointFrom<T>(arr1: T[] | Set<T>, arr2: T[] | Set<T>): boolean;
@@ -0,0 +1,212 @@
1
+ /**
2
+ * 数组排序
3
+ * @param arr 待排序数组
4
+ * @param order 排序信息, asc - 升序, desc - 倒序
5
+ * @param orderKey 如果是个对象数组,按哪个字段排序
6
+ * @returns
7
+ */
8
+ export function order(arr, order = "asc", orderKey = null) {
9
+ const collator = new Intl.Collator(undefined, { numeric: true });
10
+ return arr.sort((a, b) => {
11
+ let aValue = a;
12
+ let bValue = b;
13
+ if (typeof a === "object" && orderKey != null) {
14
+ // @ts-ignore
15
+ aValue = a[orderKey];
16
+ // @ts-ignore
17
+ bValue = b[orderKey];
18
+ }
19
+ let aGtb = -1;
20
+ if (typeof aValue === "string") {
21
+ aGtb = collator.compare(aValue, bValue);
22
+ }
23
+ else {
24
+ aGtb = aValue >= bValue ? 1 : -1;
25
+ }
26
+ return order === "asc" ? aGtb : -aGtb;
27
+ });
28
+ }
29
+ /**
30
+ * 返回所有集合交集的元素的新集合
31
+ */ export function intersection(...arrs) {
32
+ return arrs.reduce((acc, cur) => {
33
+ if (cur instanceof Set) {
34
+ //@ts-ignore
35
+ if (cur.intersection != null) {
36
+ //@ts-ignore
37
+ return acc.intersection(cur);
38
+ }
39
+ else {
40
+ const res = new Set();
41
+ for (const value of acc) {
42
+ if (cur.has(value)) {
43
+ res.add(value);
44
+ }
45
+ }
46
+ return res;
47
+ }
48
+ }
49
+ else {
50
+ return acc.filter((x) => cur.includes(x));
51
+ }
52
+ });
53
+ }
54
+ /**
55
+ * 返回一个包含第一个集合中的元素但不包含后续给定集合中元素的新集合
56
+ * @param arrs 新集合
57
+ * @returns
58
+ */
59
+ export function difference(...arrs) {
60
+ return arrs.reduce((acc, cur) => {
61
+ if (acc instanceof Set) {
62
+ //@ts-ignore
63
+ if (acc.difference != null) {
64
+ //@ts-ignore
65
+ return acc.difference(cur);
66
+ }
67
+ else {
68
+ const res = new Set();
69
+ for (const value of acc) {
70
+ if (!cur.has(value)) {
71
+ res.add(value);
72
+ }
73
+ }
74
+ return res;
75
+ }
76
+ }
77
+ else {
78
+ const res = [];
79
+ for (const value of acc) {
80
+ if (!cur.includes(value)) {
81
+ res.push(value);
82
+ }
83
+ }
84
+ return res;
85
+ }
86
+ });
87
+ }
88
+ export function union(...arrs) {
89
+ return arrs.reduce((acc, cur) => {
90
+ if (cur instanceof Set) {
91
+ //@ts-ignore
92
+ if (cur.union != null) {
93
+ //@ts-ignore
94
+ return acc.union(cur);
95
+ }
96
+ return new Set([...acc, ...cur]);
97
+ }
98
+ else {
99
+ return [...acc, ...cur];
100
+ }
101
+ });
102
+ }
103
+ /**
104
+ * 对称差: 返回一个包含此集合或给定集合中的元素的新集合,但不包含同时存在于这两个集合中的元素。
105
+ * @param arrs
106
+ * @returns
107
+ */
108
+ export function symmetricDifference(...arrs) {
109
+ return arrs.reduce((acc, cur) => {
110
+ if (cur instanceof Set) {
111
+ //@ts-ignore
112
+ if (cur.symmetricDifference != null) {
113
+ //@ts-ignore
114
+ return acc.symmetricDifference(cur);
115
+ }
116
+ const res = new Set();
117
+ for (const item of acc) {
118
+ if (!cur.has(item)) {
119
+ res.add(item);
120
+ }
121
+ }
122
+ for (const item of cur) {
123
+ if (!acc.has(item)) {
124
+ res.add(item);
125
+ }
126
+ }
127
+ return res;
128
+ }
129
+ const res = [];
130
+ for (const item of acc) {
131
+ if (!cur.includes(item)) {
132
+ res.push(item);
133
+ }
134
+ }
135
+ for (const item of cur) {
136
+ if (!acc.includes(item)) {
137
+ res.push(item);
138
+ }
139
+ }
140
+ return res;
141
+ });
142
+ }
143
+ /**
144
+ * 返回一个布尔值,指示此集合中的所有元素是否都在给定的集合中。
145
+ * @param a1
146
+ * @param a2
147
+ * @returns
148
+ */
149
+ export function isSubsetOf(a1, a2) {
150
+ //@ts-ignore
151
+ if (a1 instanceof Set && a1.isSubsetOf != null) {
152
+ //@ts-ignore
153
+ return a1.isSubsetOf(a2);
154
+ }
155
+ let is = true;
156
+ for (const item of a1) {
157
+ if (a2 instanceof Set) {
158
+ if (!a2.has(item)) {
159
+ is = false;
160
+ break;
161
+ }
162
+ }
163
+ else {
164
+ if (!a2.includes(item)) {
165
+ is = false;
166
+ break;
167
+ }
168
+ }
169
+ }
170
+ return is;
171
+ }
172
+ /**
173
+ * 返回一个布尔值,指示给定集合中的所有元素是否都在此集合中。
174
+ * @param arr1
175
+ * @param arr2
176
+ * @returns
177
+ */
178
+ export function isSupersetOf(arr1, arr2) {
179
+ return isSubsetOf(arr2, arr1);
180
+ }
181
+ /**
182
+ * 返回一个布尔值,指示此集合是否与给定集合没有公共元素。
183
+ *
184
+ * 判断两个集合是否有交集, 也可以通过 intersection(arr1, arr2).length 判断
185
+ *
186
+ * @param arr1
187
+ * @param arr2
188
+ * @returns
189
+ */
190
+ export function isDisjointFrom(arr1, arr2) {
191
+ //@ts-ignore
192
+ if (arr1 instanceof Set && arr1.isDisjointFrom != null) {
193
+ //@ts-ignore
194
+ return arr1.isDisjointFrom(arr2);
195
+ }
196
+ let is = true;
197
+ for (const item of arr1) {
198
+ if (arr2 instanceof Set) {
199
+ if (arr2.has(item)) {
200
+ is = false;
201
+ break;
202
+ }
203
+ }
204
+ else {
205
+ if (arr2.includes(item)) {
206
+ is = false;
207
+ break;
208
+ }
209
+ }
210
+ }
211
+ return is;
212
+ }