├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .npmignore
├── .vcmrc
├── .vscode
└── launch.json
├── CHANGELOG.md
├── README-CN.md
├── README.md
├── docs
├── .nojekyll
├── README.md
├── _coverpage.md
├── _media
│ └── icon.svg
├── _navbar.md
├── _sidebar.md
├── array.md
├── date.md
├── fn.md
├── index.html
├── math.md
├── net.md
├── number.md
├── object.md
├── string.md
├── verification.md
└── zh-cn
│ ├── .nojekyll
│ ├── README.md
│ ├── _coverpage.md
│ ├── _navbar.md
│ ├── _sidebar.md
│ ├── array.md
│ ├── date.md
│ ├── fn.md
│ ├── index.html
│ ├── math.md
│ ├── net.md
│ ├── number.md
│ ├── object.md
│ ├── string.md
│ └── verification.md
├── gulpfile.js
├── index.js
├── package.json
├── release
├── utils.js
└── utils.min.js
├── src
├── __test__
│ ├── import.test.ts
│ └── require.test.ts
├── array
│ ├── __test__
│ │ └── index.test.ts
│ ├── index.d.ts
│ └── index.ts
├── date
│ ├── __test__
│ │ └── index.test.ts
│ ├── index.d.ts
│ └── index.ts
├── fn
│ ├── __test__
│ │ └── index.test.ts
│ ├── index.d.ts
│ └── index.ts
├── math
│ ├── __test__
│ │ └── index.test.ts
│ ├── index.d.ts
│ └── index.ts
├── net
│ ├── __test__
│ │ └── index.test.ts
│ ├── index.d.ts
│ └── index.ts
├── number
│ ├── __test__
│ │ └── index.test.ts
│ ├── index.d.ts
│ └── index.ts
├── object
│ ├── __test__
│ │ └── index.test.ts
│ ├── index.d.ts
│ └── index.ts
├── string
│ ├── __test__
│ │ └── index.test.ts
│ ├── index.d.ts
│ └── index.ts
├── utils.d.ts
├── utils.ts
└── verification
│ ├── __test__
│ └── index.test.ts
│ ├── index.d.ts
│ └── index.ts
├── tsconfig.json
└── yarn.lock
/.eslintignore:
--------------------------------------------------------------------------------
1 | dist
2 | release
3 | validate-commit-msg.js
4 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | commonjs: true,
5 | es6: true,
6 | node: true,
7 | jest: true
8 | },
9 | extends: "eslint:recommended",
10 | parserOptions: {
11 | ecmaVersion: 2016,
12 | sourceType: "module"
13 | },
14 | parser: "typescript-eslint-parser",
15 | plugins: ["typescript"],
16 | rules: {
17 | "no-undef": "off",
18 | "no-unused-vars": "off",
19 | indent: ["error", 2],
20 | "linebreak-style": ["error", "windows"],
21 | quotes: ["error", "single"],
22 | semi: ["error", "always"]
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | example
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/.vcmrc:
--------------------------------------------------------------------------------
1 | {
2 | "types": [
3 | "feat",
4 | "fix",
5 | "docs",
6 | "style",
7 | "refactor",
8 | "perf",
9 | "test",
10 | "build",
11 | "ci",
12 | "chore",
13 | "revert"
14 | ],
15 | "scope": {
16 | "required": false,
17 | "allowed": [
18 | "*"
19 | ],
20 | "validate": false,
21 | "multiple": false
22 | },
23 | "warnOnFail": false,
24 | "maxSubjectLength": 100,
25 | "subjectPattern": ".+",
26 | "subjectPatternErrorMsg": "subject does not match subject pattern!",
27 | "helpMessage": "",
28 | "autoFix": false
29 | }
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // 使用 IntelliSense 了解相关属性。
3 | // 悬停以查看现有属性的描述。
4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "type": "node",
9 | "request": "attach",
10 | "name": "Attach by Process ID",
11 | "processId": "${command:PickProcess}",
12 | "port": 9229
13 | }
14 | ]
15 | }
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 | # 2.1.6 (2018-09-13)
3 |
4 | ## Support Tree-Shaking
5 | ```JS
6 | import { add } from 'windlike-utils/dist/math';
7 |
8 | add(0.1, 0.2); // 0.3
9 | ```
10 |
11 | ### New features
12 |
13 |
14 | # 2.1.0 (2018-09-05)
15 |
16 | ### New features
17 | `Function` Module:
18 | - add `debounce`
19 | - add `throttle`
20 |
21 | `Array` Module:
22 | - add `shallowCompare`
23 | - add `deepCompare`
24 | - remove `equal`
25 |
26 | `Object` Module:
27 | - add `shallowCompare`
28 | - add `deepCompare`
29 | - remove `valueEqual`
30 |
31 | `Math` Module:
32 | - add `add`: add the incoming parameters together, and return the result.
33 | ```js
34 | utils.math.add(0.1, 0.2); // 0.3
35 | ```
--------------------------------------------------------------------------------
/README-CN.md:
--------------------------------------------------------------------------------
1 | # Windlike-Utils · [](https://www.npmjs.com/package/windlike-utils)
2 |
3 | Windlike-Utils是一个基于函数式编程思想开发的一个工具库。
4 |
5 | * **模块化:** Windlike-Utils把工具分为若干模块,如```array```、```object```、```string```等等,方便查找和使用。
6 | * **函数式的:** 每个方法只要输入的参数相同,输出的结果也是唯一的,就像数学里的y=f(x),只要x不变,输出的y也不变,有些脏函数也做延迟输出处理,如```number.random```函数,它返回的是一个产生随机数的函数,而不是一个随机数,以保证输出的唯一性和变量的重用性。
7 | * **不可变的:** 输入的任何实参都不会被改变,而是返回新的结果。
8 |
9 | ## 安装
10 |
11 | ```npm
12 | npm install windlike-utils --save
13 | ```
14 |
15 | ## [文档](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/)
16 | - [Array](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/array)
17 | - [Date](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/date)
18 | - [Function](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/fn)
19 | - [Math](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/math)
20 | - [Net](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/net)
21 | - [Number](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/number)
22 | - [Object](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/object)
23 | - [String](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/string)
24 | - [Verification](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/verification)
25 |
26 | ## 贡献
27 | 欢迎大家踊跃提交issues和PR😄
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Windlike-Utils · [](https://www.npmjs.com/package/windlike-utils)
2 |
3 | Windlike-Utils is a tool library developed based on functional programming ideas.
4 |
5 | - **Modules:** Windlike-Utils divide the tool into several modules which like `array`、`object`、`string` and so on.It can be easily found and used.
6 | - **Functional:** Each function only has the same input parameters, and the output result is unique.Just like `y=f(x)` in mathematics.As long as `x` is unchanged, the output `y` is also unchanged.To ensure the uniqueness of the output and the reusability of the variables, Some dirty functions also do delayed output processing.For examples, `number.random` returns a function which can generate a random number, instead of the result of the random number.
7 | - **Immutable:** Any arguments entered is immutable and new results will be returned.
8 | - **Tree-Shaking:** Support Tree-Shaking.
9 |
10 | ## Install
11 |
12 | ```npm
13 | npm install windlike-utils --save
14 | ```
15 |
16 | ## Feature
17 |
18 | - Format date:
19 |
20 | ```js
21 | const ms = 837043200000; // 1996-07-11 08:00:00
22 |
23 | utils.date.createFormatDate("YYYY-MM-DD hh:mm:ss w")(ms); // 1996-07-11 08:00:00 Thur.
24 | utils.date.createFormatDate("YY-MM-DD hh:mm:ss W")(ms); // 96-07-11 08:00:00 星期四
25 | ```
26 |
27 | - Currying
28 |
29 | ```js
30 | const add = (a: number, b: number, c: number): number => a + b + c;
31 | const curryAdd: any = utils.fn.curry(add);
32 |
33 | curryAdd(1, 2, 3); // 6
34 | curryAdd(1, 2)(4); // 7
35 | curryAdd(1)(3)(5); // 9
36 | curryAdd(1)(2, 3); // 6
37 | ```
38 |
39 | - Parse Url
40 |
41 | ```js
42 | const URL = 'https://github.com/MrWindlike/Windlike-Utils?key=value';
43 | const result = utils.net.parseUrl(URL);
44 | // {
45 | // url: URL,
46 | // host: 'https://github.com',
47 | // port: 80,
48 | // path: '/MrWindlike/Windlike-Utils',
49 | // params: {
50 | // key: 'value',
51 | // },
52 | // }
53 | ```
54 |
55 | ## [DOCS](https://mrwindlike.github.io/Windlike-Utils/#/)
56 |
57 | - [Array](https://mrwindlike.github.io/Windlike-Utils/#/array)
58 | - [Date](https://mrwindlike.github.io/Windlike-Utils/#/date)
59 | - [Function](https://mrwindlike.github.io/Windlike-Utils/#/fn)
60 | - [Math](https://mrwindlike.github.io/Windlike-Utils/#/math)
61 | - [Net](https://mrwindlike.github.io/Windlike-Utils/#/net)
62 | - [Number](https://mrwindlike.github.io/Windlike-Utils/#/number)
63 | - [Object](https://mrwindlike.github.io/Windlike-Utils/#/object)
64 | - [String](https://mrwindlike.github.io/Windlike-Utils/#/string)
65 | - [Verification](https://mrwindlike.github.io/Windlike-Utils/#/verification)
66 |
67 | ## Contribute
68 |
69 | Open an issue or PR.😄
70 |
--------------------------------------------------------------------------------
/docs/.nojekyll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrWindlike/Windlike-Utils/2c5c10c37b3ae11967a1d5a26d0fc06162394203/docs/.nojekyll
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Windlike-Utils · [](https://www.npmjs.com/package/windlike-utils)
2 |
3 | Windlike-Utils is a tool library developed based on functional programming ideas.
4 |
5 | - **Modules:** Windlike-Utils divide the tool into several modules which like `array`、`object`、`string` and so on.It can be easily found and used.
6 | - **Functional:** Each function only has the same input parameters, and the output result is unique.Just like `y=f(x)` in mathematics.As long as `x` is unchanged, the output `y` is also unchanged.To ensure the uniqueness of the output and the reusability of the variables, Some dirty functions also do delayed output processing.For examples, `number.random` returns a function which can generate a random number, instead of the result of the random number.
7 | - **Immutable:** Any arguments entered is immutable and new results will be returned.
8 |
9 | ## Install
10 |
11 | ```npm
12 | npm install windlike-utils --save
13 | ```
14 |
15 | ## Feature
16 |
17 | - Format date:
18 |
19 | ```js
20 | const ms = 837043200000; // 1996-07-11 08:00:00
21 |
22 | utils.date.createFormatDate("YYYY-MM-DD hh:mm:ss w")(ms); // 1996-07-11 08:00:00 Thur.
23 | utils.date.createFormatDate("YY-MM-DD hh:mm:ss W")(ms); // 96-07-11 08:00:00 星期四
24 | ```
25 |
26 | - Currying
27 |
28 | ```js
29 | const add = (a: number, b: number, c: number): number => a + b + c;
30 | const curryAdd: any = utils.fn.curry(add);
31 |
32 | curryAdd(1, 2, 3); // 6
33 | curryAdd(1, 2)(4); // 7
34 | curryAdd(1)(3)(5); // 9
35 | curryAdd(1)(2, 3); // 6
36 | ```
37 |
38 | - Parse Url
39 |
40 | ```js
41 | const URL = 'https://github.com/MrWindlike/Windlike-Utils?key=value';
42 | const result = utils.net.parseUrl(URL);
43 | // {
44 | // url: URL,
45 | // host: 'https://github.com',
46 | // port: 80,
47 | // path: '/MrWindlike/Windlike-Utils',
48 | // params: {
49 | // key: 'value',
50 | // },
51 | // }
52 | ```
53 |
54 |
55 | # 2.1.6 (2018-09-13)
56 |
57 | ## Support Tree-Shaking
58 | ```JS
59 | import { add } from 'windlike-utils/dist/math';
60 |
61 | add(0.1, 0.2); // 0.3
62 | ```
63 |
64 |
65 | # 2.1.0 (2018-09-05)
66 |
67 | ### New features
68 | `Function` Module:
69 | - add `debounce`
70 | - add `throttle`
71 |
72 | `Array` Module:
73 | - add `shallowCompare`
74 | - add `deepCompare`
75 | - remove `equal`
76 |
77 | `Object` Module:
78 | - add `shallowCompare`
79 | - add `deepCompare`
80 | - remove `valueEqual`
81 |
82 | `Math` Module:
83 | - add `add`: add the incoming parameters together, and return the result.
84 | ```js
85 | utils.math.add(0.1, 0.2); // 0.3
86 | ```
87 |
88 | ## Contribute
89 |
90 | Open an issue or PR.😄
91 |
--------------------------------------------------------------------------------
/docs/_coverpage.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Windlike-Utils 2.1.0
4 |
5 | > A tool library developed based on functional programming ideas.
6 |
7 | - Friendly editor prompt support
8 | - Simple & Convenience
9 | - Several Modules
10 |
11 |
12 | [GitHub](https://github.com/MrWindlike/Windlike-Utils)
13 | [Get Started](#windlike-utils-middot-)
--------------------------------------------------------------------------------
/docs/_media/icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/_navbar.md:
--------------------------------------------------------------------------------
1 | - Translations
2 | - [:uk: English](/)
3 | - [:cn: 中文](/zh-cn/)
--------------------------------------------------------------------------------
/docs/_sidebar.md:
--------------------------------------------------------------------------------
1 | * [Windlike-Utils](README.md)
2 | * API
3 | * [Array (new)](array.md)
4 | * [Date](date.md)
5 | * [Function (new)](fn.md)
6 | * [Math (new)](math.md)
7 | * [Net](net.md)
8 | * [Number](number.md)
9 | * [Object (new)](object.md)
10 | * [String](string.md)
11 | * [Verification](verification.md)
12 | * [Contribute](contribute.md)
13 |
--------------------------------------------------------------------------------
/docs/array.md:
--------------------------------------------------------------------------------
1 | # Array
2 | ```js
3 | interface ArrayModule {
4 | compareLength: (firstArray: any[], secondArray: any[]) => number;
5 | equal: (firstArray: T[], secondArray: T[]) => boolean;
6 | deleteItem: (array: T[], value: T) => T[];
7 | deleteItems: (array: T[], value: T) => T[];
8 | deleteItemsExcept: (array: T[], exceptArray: T[]) => T[];
9 | map: (fn: any) => (array: T[]) => T[];
10 | }
11 | ```
12 |
13 | ## compareLength
14 | #### Describe
15 | Compare the length of two arrays.
16 | ```js
17 | (firstArray: any[], secondArray: any[]) => number;
18 | ```
19 |
20 | #### Arguments
21 | - firstArray(any[])
22 | - secondArray(any[])
23 |
24 | #### Returns
25 | (number): The difference between the length of the first array and the length of the second array.
26 |
27 | #### Example
28 | ```js
29 | const firstArray = [1, 2, 3, {}];
30 | const secondArray = [{}, 3, 2, 1];
31 | const result: number = utils.array.compareLength(firstArray, secondArray); // 0
32 | ```
33 |
34 | ## shallowCompare
35 | #### Describe
36 | Compare the values of two arrays.
37 | ```js
38 | (firstArray: T[], secondArray: T[]) => boolean;
39 | ```
40 |
41 | #### Arguments
42 | - firstArray(any[])
43 | - secondArray(any[])
44 |
45 | #### Returns
46 | (boolean)
47 |
48 | #### Example
49 | ```js
50 | utils.array.shallowCompare([1, 2], [1, 2]); // true
51 | utils.array.shallowCompare([1, 2, { key: 'value' }], [1, 2, { key: 'value' }]); // false
52 | ```
53 |
54 | ## deepCompare
55 | #### Describe
56 | Compare the values of two arrays.
57 | ```js
58 | (firstArray: T[], secondArray: T[]) => boolean;
59 | ```
60 |
61 | #### Arguments
62 | - firstArray(any[])
63 | - secondArray(any[])
64 |
65 | #### Returns
66 | (boolean)
67 |
68 | #### Example
69 | ```js
70 | utils.array.shallowCompare([1, 2], [1, 2]); // true
71 | utils.array.shallowCompare([1, 2, { key: 'value' }], [1, 2, { key: 'value' }]); // true
72 | ```
73 |
74 | ## deleteItem
75 | #### Describe
76 | Delete the first item in the array equal to the value and return a new array.
77 | ```js
78 | (array: T[], value: T) => T[];
79 | ```
80 |
81 | #### Arguments
82 | - array(T[])
83 | - value(T)
84 |
85 | #### Returns
86 | (T[])
87 |
88 | #### Example
89 | ```js
90 | const array = [1, 2, 3];
91 |
92 | utils.array.deleteItem(array, 2); // [1, 3]
93 | ```
94 |
95 | ## deleteItems
96 | #### Describe
97 | Delete the all items in the array equal to the value and return a new array.
98 | ```js
99 | (array: T[], value: T) => T[];
100 | ```
101 |
102 | #### Arguments
103 | - array(T[])
104 | - value(T)
105 |
106 | #### Returns
107 | (T[])
108 |
109 | #### Example
110 | ```js
111 | const array = [1, 9, 9, 6];
112 |
113 | utils.array.deleteItems(array, 9); // [1, 6]
114 | ```
115 |
116 | ## deleteItemsExcept
117 | #### Describe
118 | Delete values that are not in another array in the array.
119 | ```js
120 | (array: T[], exceptArray: T[]) => T[];
121 | ```
122 |
123 | #### Arguments
124 | - array(T[])
125 | - exceptArray(T[])
126 |
127 | #### Returns
128 | (T[])
129 |
130 | #### Example
131 | ```js
132 | const array = [1, '9', 9, 6];
133 |
134 | utils.array.deleteItemsExcept(array, [1, 2, 3]); // [1]
135 | utils.array.deleteItemsExcept(array, [1, 9, 3]); // [1, 9]
136 | utils.array.deleteItemsExcept(array, [1, '9', 6]); // [1, '9', 6]
137 | ```
138 |
139 | ## map
140 | #### Describe
141 | ```js
142 | (fn: any) => (array: T[]) => T[]
143 | ```
144 |
145 | #### Arguments
146 | - fn: callback function
147 |
148 | #### Returns
149 | (```(array: T[]) => T[]```)
150 |
151 | #### Example
152 | ```js
153 | const plusOne = (value) => 1 + value;
154 | const array = [1, 9, 9, 6];
155 | const plusOneMap = utils.array.map(plusOne);
156 |
157 | plusOneMap(array); // [2, 10, 10, 7]
158 | ```
159 |
--------------------------------------------------------------------------------
/docs/date.md:
--------------------------------------------------------------------------------
1 | # Date
2 | ```js
3 | interface DateModule {
4 | createFormatDate: (format: string) => (date: number) => string;
5 | }
6 | ```
7 |
8 | ## createFormatDate
9 | #### Describe
10 | Create a function to format date.
11 | ```js
12 | (format: string) => (date: number) => string;
13 | ```
14 |
15 | #### Arguments
16 | - format(string): Y: Year;M: Month;D: Day;h: Hour;m: Minute;s: Second;w: Week(en);W: Week(cn)
17 |
18 | #### Returns
19 | (```(ms: number) => string;```)
20 |
21 | #### Example
22 | ```js
23 | const ms = 837043200000; // 1996-07-11 08:00:00
24 |
25 | utils.date.createFormatDate('YYYY-MM-DD hh:mm:ss w')(ms); // 1996-07-11 08:00:00 Thur.
26 | utils.date.createFormatDate('YY-MM-DD hh:mm:ss W')(ms); // 96-07-11 08:00:00 星期四
27 | ```
--------------------------------------------------------------------------------
/docs/fn.md:
--------------------------------------------------------------------------------
1 | # Fn
2 | ```js
3 | interface FunctionModule {
4 | curry: (fn: (...params: any[]) => Return) => CurryFunction;
5 | compose: (...fn: any[]) => (...params: any[]) => Return;
6 | }
7 |
8 | interface CurryFunction {
9 | (...newParams: any[]): Return | CurryFunction
10 | }
11 | ```
12 |
13 | ## curry
14 | #### Describe
15 | ```js
16 | interface CurryFunction {
17 | (...newParams: any[]): Return | CurryFunction
18 | }
19 |
20 | (fn: (...params: any[]) => Return) => CurryFunction;
21 | ```
22 |
23 | #### Arguments
24 | - fn(```(...params: any[]) => Return) => CurryFunction```)
25 |
26 | #### Returns
27 | (```CurryFunction```)
28 |
29 | #### Example
30 | ```js
31 | const add = (a: number, b: number, c: number): number => a + b + c;
32 | const curryAdd: any = utils.fn.curry(add);
33 |
34 | curryAdd(1, 2, 3); // 6
35 | curryAdd(1, 2)(4); // 7
36 | curryAdd(1)(3)(5); // 9
37 | curryAdd(1)(2, 3); // 6
38 | ```
39 |
40 | ## compose
41 | #### Describe
42 | Compose the functions from right to left.
43 | ```js
44 | (...fn: any[]) => (...params: any[]) => Return;
45 | ```
46 |
47 | #### Arguments
48 | - ...fn(any[])
49 |
50 | #### Returns
51 | (```(...params: any[]) => Return```)
52 |
53 | #### Example
54 | ```js
55 | const plusOne = (num) => num * 1 + 1;
56 | const double = (num) => num * 2;
57 | const plusOneAndDouble = utils.fn.compose(double, plusOne); // 先加一后乘二
58 |
59 | plusOneAndDouble(1); // 4
60 | plusOneAndDouble(2); // 6
61 | ```
62 |
63 | ## debounce
64 | #### Describe
65 | Change multiple consecutive executions over a period of time.
66 | ```js
67 | (
68 | fn: (...params: any[]) => Return,
69 | wait: number,
70 | immediate: boolean
71 | ) => Executor;
72 | ```
73 |
74 | #### Arguments
75 | - fn
76 | - wait
77 | - immediate: is execute immediately?
78 |
79 | #### Returns
80 | ```
81 | interface Executor {
82 | execute: (...params: any[]) => (Return | null);
83 | result: Return;
84 | }
85 | ```
86 | `Executor`
87 |
88 | #### Example
89 | ```js
90 | const executor = utils.fn.debounce(
91 | fetch,
92 | 300,
93 | false
94 | );
95 |
96 | input.addEvetListener('input', function(e) {
97 | const result = executor.execute('/api');
98 | });
99 |
100 | const result = excutor.result; // get current result
101 | ```
102 |
103 | ## throttle
104 | #### Describe
105 | Reduce the frequency of execution
106 |
107 | ```js
108 | interface ThrottleOptions {
109 | isExecuteAtStart: boolean; // default is true
110 | isExecuteAtEnd: boolean; // default is true
111 | }
112 |
113 | (
114 | fn: (...params: any[]) => Return,
115 | wait: number,
116 | options?: ThrottleOptions
117 | ) => Executor;
118 | ```
119 |
120 | #### Arguments
121 | - fn
122 | - wait
123 | - options?
124 |
125 | #### Returns
126 | ```
127 | interface Executor {
128 | execute: (...params: any[]) => (Return | null);
129 | result: Return;
130 | }
131 | ```
132 | `Executor`
133 |
134 | #### Example
135 | ```js
136 | const executor = utils.fn.throttle(
137 | fetch,
138 | 300,
139 | {
140 | isExecuteAtStart: true,
141 | isExecuteAtEnd: false,
142 | }
143 | );
144 |
145 | input.addEvetListener('click', function(e) {
146 | const result = executor.execute('/api');
147 | });
148 |
149 | const result = excutor.result; // get current result
150 | ```
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Windlike-Utils
7 |
8 |
9 |
10 |
11 |
16 |
17 |
18 |
22 | Loading...
23 |
24 |
32 |
34 |
35 |
--------------------------------------------------------------------------------
/docs/math.md:
--------------------------------------------------------------------------------
1 | # Math
2 | ```js
3 | interface MathModule {
4 | createSin: (height: number, width: number, offset: number) => (x: number) => number;
5 | createGetPointOnCircle: (radius: number, offsetX: number, offsetY: number) => (radian: number) => Point;
6 | }
7 |
8 | interface Point {
9 | x: number;
10 | y: number;
11 | }
12 | ```
13 |
14 | ## createSin
15 | #### Describe
16 | y=f(x)=height \* sin(width \* x + offset)。
17 | ```js
18 | (height: number, width: number, offset: number) => (x: number) => number;
19 | ```
20 |
21 | #### Arguments
22 | - height(number)
23 | - width(number)
24 | - offset(number)
25 |
26 | #### Returns
27 | (```(x: number) => number```)
28 |
29 | #### Example
30 | ```js
31 | const sin = utils.math.createSin(2, 2, Math.PI / 2);
32 |
33 | sin(Math.PI / 2); // -2
34 | ```
35 |
36 | ## createGetPointOnCircle
37 | #### Describe
38 | Create a function to get the point on the circle.
39 | ```js
40 | interface Point {
41 | x: number;
42 | y: number;
43 | }
44 |
45 | (radius: number, offsetX: number, offsetY: number) => (radian: number) => Point;
46 | ```
47 |
48 | #### Arguments
49 | - radius(number)
50 | - offsetX(number)
51 | - offsetY(number)
52 |
53 | #### Returns
54 | (```(radian: number) => Point```)
55 |
56 | #### Example
57 | ```js
58 | const getPointOnCircle = utils.math.createGetPointOnCircle(4, 10, 5);
59 |
60 | getPointOnCircle(0); // { x: 14, y: 5 }
61 | ```
62 |
63 | ## add
64 | #### Describe
65 | add the incoming parameters together, and return the result.
66 | ```js
67 | (...numbers: number[])=> number;
68 | ```
69 |
70 | #### Arguments
71 | - ...numbers
72 |
73 | #### Returns
74 | (```number```)
75 |
76 | #### Example
77 | ```js
78 | utils.math.add(0.1, 0.2); // 0.3
79 | ```
80 |
--------------------------------------------------------------------------------
/docs/net.md:
--------------------------------------------------------------------------------
1 | # Net
2 | ```js
3 | interface NetModule {
4 | parseParams: (locationSearch: string) => object;
5 | parseUrl: (url: string) => UrlInfoObject;
6 | }
7 |
8 | interface UrlInfoObject {
9 | url: string
10 | host: string
11 | port: number
12 | path: string
13 | params: object
14 | }
15 | ```
16 |
17 | ## parseParams
18 | #### Describe
19 | ```js
20 | (locationSearch: string) => object;
21 | ```
22 |
23 | #### Arguments
24 | - locationSearch(string)
25 |
26 | #### Returns
27 | (object)
28 |
29 | #### Example
30 | ```js
31 | const SEARCH = '?key=value&search=windlike';
32 |
33 | utils.net.parseParams(SEARCH); // { key: 'value', search: 'windlike' }
34 | ```
35 |
36 | ## parseUrl
37 | Parse URL string to object.
38 | #### Describe
39 | ```js
40 | interface UrlInfoObject {
41 | url: string
42 | host: string
43 | port: number
44 | path: string
45 | params: object
46 | }
47 |
48 | (url: string) => UrlInfoObject;
49 | ```
50 |
51 | #### Arguments
52 | - url(string)
53 |
54 | #### Returns
55 | (UrlInfoObject)
56 |
57 | #### Example
58 | ```js
59 | const URL = 'https://github.com/MrWindlike/Windlike-Utils?key=value';
60 |
61 | utils.net.parseUrl(URL);
62 | // {
63 | // url: URL,
64 | // host: 'https://github.com',
65 | // port: 80,
66 | // path: '/MrWindlike/Windlike-Utils',
67 | // params: {
68 | // key: 'value',
69 | // },
70 | // }
71 | ```
--------------------------------------------------------------------------------
/docs/number.md:
--------------------------------------------------------------------------------
1 | # Number
2 | ```js
3 | interface NumberModule {
4 | createRandomFunction: (min: number, max: number, float: boolean) => () => number;
5 | }
6 | ```
7 |
8 | ## createRandomFunction
9 | #### Describe
10 | Create a function to generate a random number.
11 | ```js
12 | (min: number, max: number, float: boolean) => () => number;
13 | ```
14 |
15 | #### Arguments
16 | - min(number)
17 | - max(number)
18 | - float(boolean)
19 |
20 | #### Returns
21 | (```() => number```)
22 |
23 | #### Example
24 | ```js
25 | const createRandom = utils.number.createRandomFunction(100, 1, true);
26 |
27 | createRandom();
28 | ```
--------------------------------------------------------------------------------
/docs/object.md:
--------------------------------------------------------------------------------
1 | # Object
2 | ```js
3 | interface ObjectModule {
4 | valueEqual: (firstObj: AnyObject, secondObj: AnyObject) => boolean
5 | }
6 | ```
7 |
8 | ## shallowCompare
9 | #### Describe
10 | Determine if the values of two objects are equal.
11 | ```js
12 | (firstObj: AnyObject, secondObj: AnyObject) => boolean;
13 | ```
14 |
15 | #### Arguments
16 | - firstObj(object)
17 | - secondObj(object)
18 |
19 | #### Returns
20 | (boolean)
21 |
22 | #### Example
23 | ```js
24 | utils.object.shallowCompare(
25 | {
26 | a: 1,
27 | b: 2,
28 | },
29 | {
30 | b: 2,
31 | a: 1,
32 | },
33 | ); // true
34 |
35 | utils.object.shallowCompare(
36 | {
37 | a: 1,
38 | child: {
39 | key: 'value'
40 | },
41 | b: 2,
42 | obj: {},
43 | },
44 | {
45 | b: 2,
46 | obj: {},
47 | a: 1,
48 | child: {
49 | key: 'value'
50 | },
51 | },
52 | ); // false
53 |
54 | ```
55 |
56 | ## deepCompare
57 | #### Describe
58 | Determine if the values of two objects are equal.
59 | ```js
60 | (firstObj: AnyObject, secondObj: AnyObject) => boolean;
61 | ```
62 |
63 | #### Arguments
64 | - firstObj(object)
65 | - secondObj(object)
66 |
67 | #### Returns
68 | (boolean)
69 |
70 | #### Example
71 | ```js
72 | utils.object.deepCompare(
73 | {
74 | a: 1,
75 | child: {
76 | key: 'value'
77 | },
78 | b: 2,
79 | obj: {},
80 | },
81 | {
82 | b: 2,
83 | obj: {},
84 | a: 1,
85 | child: {
86 | key: 'value'
87 | },
88 | },
89 | ); // true
90 |
91 | ```
92 |
93 | ## has
94 | #### Describe
95 | Determine if the object has the key.
96 | ```js
97 | (object: AnyObject, key: string) => boolean;
98 | ```
99 |
100 | #### Arguments
101 | - object(object)
102 | - key(string)
103 |
104 | #### Returns
105 | (boolean)
106 |
107 | #### Example
108 | ```js
109 | const object = { key: 'value', nonexistent: undefined };
110 |
111 | utils.object.has(object, 'key'); // true
112 | utils.object.has(object, 'nonexistent'); // false
113 | ```
--------------------------------------------------------------------------------
/docs/string.md:
--------------------------------------------------------------------------------
1 | # String
2 | ```js
3 | interface StringModule {
4 | replace: (match: RegExp | string) => (str: string, substitute: any) => string;
5 | split: (char: string | RegExp) => (str: string) => string[];
6 | match: (regexp: RegExp) => (str: string) => string[];
7 | }
8 | ```
9 |
10 | ## replace
11 | #### Describe
12 | ```js
13 | (match: RegExp | string) => (str: string, substitute: any) => string;
14 | ```
15 |
16 | #### Arguments
17 | - match(RegExp | string)
18 |
19 | #### Returns
20 | (```(str: string, substitute: any) => string```)
21 |
22 | #### Example
23 | ```js
24 | const str = 'I\'m Windlike.';
25 | const replaceWindlike = utils.string.replace('Windlike');
26 |
27 | replaceWindlike(str, 'I'); // I'm I.
28 | ```
29 |
30 | ## split
31 | #### Describe
32 | ```js
33 | (char: string | RegExp) => (str: string) => string[];
34 | ```
35 |
36 | #### Arguments
37 | - char(RegExp | string): 分割符
38 |
39 | #### Returns
40 | (```(str: string) => string[]```)
41 |
42 | #### Example
43 | ```js
44 | const str = 'I And You';
45 | const splitSpace = utils.string.split(' ');
46 |
47 | splitSpace(str); // ['I', 'And', 'You']
48 | ```
49 |
50 | ## match
51 | #### Describe
52 | ```js
53 | (regexp: RegExp) => (str: string) => string[];
54 | ```
55 |
56 | #### Arguments
57 | - regexp(RegExp)
58 |
59 | #### Returns
60 | (```(str: string) => string[]```)
61 |
62 | #### Example
63 | ```js
64 | const re = /[\w]+/g;
65 | const str = 'I am a string.';
66 | const matchWork = utils.string.match(re);
67 |
68 | matchWork(str); // ['I', 'am', 'a', 'string']
69 | ```
--------------------------------------------------------------------------------
/docs/verification.md:
--------------------------------------------------------------------------------
1 | # Verification
2 | ```js
3 | interface VerificationModule {
4 | readonly _phoneRE: RegExp;
5 | readonly _emailRE: RegExp;
6 |
7 | checkRe: (re: RegExp) => (checkedStr: string) => boolean;
8 | checkLength: (min: number, max: number) => (str: string) => boolean;
9 | check: (checkType: CheckType) => (checkedStr: string) => boolean;
10 | [prop: string]: any
11 | }
12 |
13 | type CheckType = 'phone' | 'email';
14 | ```
15 |
16 | ## checkRe
17 | #### Describe
18 | ```js
19 | (re: RegExp) => (checkedStr: string) => boolean;
20 | ```
21 |
22 | #### Arguments
23 | - re(RegExp)
24 |
25 | #### Returns
26 | (```(checkedStr: string) => boolean```)
27 |
28 | #### Example
29 | ```js
30 | const checkFunction = utils.verification.checkRe(/<[\s\S]*?(script)[\s\S]*?>/);
31 |
32 | checkFunction(''); // true
33 | checkFunction(''); // true
34 | checkFunction(''); // true
35 | ```
36 |
37 | ## checkLength
38 | #### Describe
39 | ```js
40 | (min: number, max: number) => (str: string) => boolean;
41 | ```
42 |
43 | #### Arguments
44 | - min(number)
45 | - max(number)
46 |
47 | #### Returns
48 | (```(str: string) => boolean```)
49 |
50 | #### Example
51 | ```js
52 | const checkStringLength = utils.verification.checkLength(1, 5);
53 |
54 | checkStringLength('windlike'); // false
55 | checkStringLength('wind'); // true
56 | ```
57 |
58 | ## check
59 | #### Describe
60 | ```js
61 | type CheckType = 'phone' | 'email';
62 |
63 | (checkType: CheckType) => (checkedStr: string) => boolean;
64 | ```
65 |
66 | #### Arguments
67 | - checkType(CheckType): 'phone' | 'email'
68 |
69 | #### Returns
70 | (```(checkedStr: string) => boolean```)
71 |
72 | #### Example
73 | ```js
74 | const checkPhone = utils.verification.check('phone');
75 | const checkEmail = utils.verification.check('email');
76 |
77 | checkPhone('13800000000'); // true
78 | checkEmail('windlike@windlike.com'); // true
79 | ```
--------------------------------------------------------------------------------
/docs/zh-cn/.nojekyll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrWindlike/Windlike-Utils/2c5c10c37b3ae11967a1d5a26d0fc06162394203/docs/zh-cn/.nojekyll
--------------------------------------------------------------------------------
/docs/zh-cn/README.md:
--------------------------------------------------------------------------------
1 | # Windlike-Utils · [](https://www.npmjs.com/package/windlike-utils)
2 |
3 | Windlike-Utils是一个基于函数式编程思想开发的一个工具库。
4 |
5 | * **模块化:** Windlike-Utils把工具分为若干模块,如```array```、```object```、```string```等等,方便查找和使用。
6 | * **函数式的:** 每个方法只要输入的参数相同,输出的结果也是唯一的,就像数学里的y=f(x),只要x不变,输出的y也不变,有些脏函数也做延迟输出处理,如```number.random```函数,它返回的是一个产生随机数的函数,而不是一个随机数,以保证输出的唯一性和变量的重用性。
7 | * **不可变的:** 输入的任何实参都不会被改变,而是返回新的结果。
8 |
9 | ## 安装
10 |
11 | ```npm
12 | npm install windlike-utils --save
13 | ```
14 |
15 | ## [文档](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/)
16 | - [Array](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/array)
17 | - [Date](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/date)
18 | - [Function](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/fn)
19 | - [Math](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/math)
20 | - [Net](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/net)
21 | - [Number](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/number)
22 | - [Object](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/object)
23 | - [String](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/string)
24 | - [Verification](https://mrwindlike.github.io/Windlike-Utils/zh-cn/#/verification)
25 |
26 | ## 贡献
27 | 欢迎大家踊跃提交issues和PR😄
--------------------------------------------------------------------------------
/docs/zh-cn/_coverpage.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Windlike-Utils 2.0.9
4 |
5 | > 基于函数式编程思想的工具库
6 |
7 | - 友好的编辑器提示支持
8 | - 简单、方便
9 | - 多个模块
10 |
11 |
12 | [GitHub](https://github.com/MrWindlike/Windlike-Utils)
13 | [Get Started](#windlike-utils-middot-)
--------------------------------------------------------------------------------
/docs/zh-cn/_navbar.md:
--------------------------------------------------------------------------------
1 | - Translations
2 | - [:uk: English](/)
3 | - [:cn: 中文](/zh-cn/)
--------------------------------------------------------------------------------
/docs/zh-cn/_sidebar.md:
--------------------------------------------------------------------------------
1 | * [Windlike-Utils](./README.md)
2 | * API
3 | * [Array](/zh-cn/array.md)
4 | * [Date](/zh-cn/date.md)
5 | * [Function](/zh-cn/fn.md)
6 | * [Math](/zh-cn/math.md)
7 | * [Net](/zh-cn/net.md)
8 | * [Number](/zh-cn/number.md)
9 | * [Object](/zh-cn/object.md)
10 | * [String](/zh-cn/string.md)
11 | * [Verification](/zh-cn/verification.md)
12 | * [Contribute](/zh-cn/contribute.md)
13 |
--------------------------------------------------------------------------------
/docs/zh-cn/array.md:
--------------------------------------------------------------------------------
1 | # Array
2 | ```js
3 | interface ArrayModule {
4 | compareLength: (firstArray: any[], secondArray: any[]) => number;
5 | equal: (firstArray: T[], secondArray: T[]) => boolean;
6 | deleteItem: (array: T[], value: T) => T[];
7 | deleteItems: (array: T[], value: T) => T[];
8 | deleteItemsExcept: (array: T[], exceptArray: T[]) => T[];
9 | map: (fn: any) => (array: T[]) => T[];
10 | }
11 | ```
12 |
13 | ## compareLength
14 | #### Describe
15 | 比较两个数组的长度。
16 | ```js
17 | (firstArray: any[], secondArray: any[]) => number;
18 | ```
19 |
20 | #### Arguments
21 | - firstArray(any[])
22 | - secondArray(any[])
23 |
24 | #### Returns
25 | (number): 第一个数组长度与第二个数组长度的差值。
26 |
27 | #### Example
28 | ```js
29 | const firstArray = [1, 2, 3, {}];
30 | const secondArray = [{}, 3, 2, 1];
31 | const result: number = utils.array.compareLength(firstArray, secondArray); // 0
32 | ```
33 |
34 | ## equal
35 | #### Describe
36 | 比较两个数组的值,使用严格等于进行比较。
37 | ```js
38 | (firstArray: T[], secondArray: T[]) => boolean;
39 | ```
40 |
41 | #### Arguments
42 | - firstArray(any[])
43 | - secondArray(any[])
44 |
45 | #### Returns
46 | (boolean)
47 |
48 | #### Example
49 | ```js
50 | utils.array.equal([1, 2], [1, 2]); // true
51 | utils.array.equal([1, 2, { key: 'value' }], [1, 2, { key: 'value' }]); // false
52 | ```
53 |
54 | ## deleteItem
55 | #### Describe
56 | 删除数组里第一个找到的值,然后返回新数组。
57 | ```js
58 | (array: T[], value: T) => T[];
59 | ```
60 |
61 | #### Arguments
62 | - array(T[])
63 | - value(T): 要删除的值
64 |
65 | #### Returns
66 | (T[]): 返回的新数组
67 |
68 | #### Example
69 | ```js
70 | const array = [1, 2, 3];
71 |
72 | utils.array.deleteItem(array, 2); // [1, 3]
73 | ```
74 |
75 | ## deleteItems
76 | #### Describe
77 | 删除数组里所有与值相等的项,然后返回新数组。
78 | ```js
79 | (array: T[], value: T) => T[];
80 | ```
81 |
82 | #### Arguments
83 | - array(T[])
84 | - value(T): 要删除的值
85 |
86 | #### Returns
87 | (T[]): 返回的新数组
88 |
89 | #### Example
90 | ```js
91 | const array = [1, 9, 9, 6];
92 |
93 | utils.array.deleteItems(array, 9); // [1, 6]
94 | ```
95 |
96 | ## deleteItemsExcept
97 | #### Describe
98 | 删除数组里另外一个数组里没有的值。
99 | ```js
100 | (array: T[], exceptArray: T[]) => T[];
101 | ```
102 |
103 | #### Arguments
104 | - array(T[])
105 | - exceptArray(T[]): 不要删除的值
106 |
107 | #### Returns
108 | (T[]): 返回的新数组
109 |
110 | #### Example
111 | ```js
112 | const array = [1, '9', 9, 6];
113 |
114 | utils.array.deleteItemsExcept(array, [1, 2, 3]); // [1]
115 | utils.array.deleteItemsExcept(array, [1, 9, 3]); // [1, 9]
116 | utils.array.deleteItemsExcept(array, [1, '9', 6]); // [1, '9', 6]
117 | ```
118 |
119 | ## deleteItemsExcept
120 | #### Describe
121 | 对原生数组```map```进行的封装。
122 | ```js
123 | (fn: any) => (array: T[]) => T[]
124 | ```
125 |
126 | #### Arguments
127 | - fn: ```map```要执行的回调函数
128 |
129 | #### Returns
130 | (```(array: T[]) => T[]```): 需要传入数组做为参数的函数
131 |
132 | #### Example
133 | ```js
134 | const plusOne = (value) => 1 + value;
135 | const array = [1, 9, 9, 6];
136 | const plusOneMap = utils.array.map(plusOne);
137 |
138 | plusOneMap(array); // [2, 10, 10, 7]
139 | ```
140 |
--------------------------------------------------------------------------------
/docs/zh-cn/date.md:
--------------------------------------------------------------------------------
1 | # Date
2 | ```js
3 | interface DateModule {
4 | createFormatDate: (format: string) => (date: number) => string;
5 | }
6 | ```
7 |
8 | ## createFormatDate
9 | #### Describe
10 | 创建格式化日期的函数。
11 | ```js
12 | (format: string) => (date: number) => string;
13 | ```
14 |
15 | #### Arguments
16 | - format(string): 日期的格式。Y:年;M:月;D:日;h:时;m:分;s:秒;w:星期(英);W:星期(中)。
17 |
18 | #### Returns
19 | (```(ms: number) => string;```): 需要传入毫秒数作为参数的函数,返回格式化后的日期字符串。
20 |
21 | #### Example
22 | ```js
23 | const ms = 837043200000; // 1996-07-11 08:00:00
24 |
25 | utils.date.createFormatDate('YYYY-MM-DD hh:mm:ss w')(ms); // 1996-07-11 08:00:00 Thur.
26 | utils.date.createFormatDate('YY-MM-DD hh:mm:ss W')(ms); // 96-07-11 08:00:00 星期四
27 | ```
--------------------------------------------------------------------------------
/docs/zh-cn/fn.md:
--------------------------------------------------------------------------------
1 | # Fn
2 | ```js
3 | interface FunctionModule {
4 | curry: (fn: (...params: any[]) => Return) => CurryFunction;
5 | compose: (...fn: any[]) => (...params: any[]) => Return;
6 | }
7 |
8 | interface CurryFunction {
9 | (...newParams: any[]): Return | CurryFunction
10 | }
11 | ```
12 |
13 | ## curry
14 | #### Describe
15 | 将函数柯里化。
16 | ```js
17 | interface CurryFunction {
18 | (...newParams: any[]): Return | CurryFunction
19 | }
20 |
21 | (fn: (...params: any[]) => Return) => CurryFunction;
22 | ```
23 |
24 | #### Arguments
25 | - fn(```(...params: any[]) => Return) => CurryFunction```): 需要柯里化的函数。
26 |
27 | #### Returns
28 | (```CurryFunction```): 返回新的函数或者结果。
29 |
30 | #### Example
31 | ```js
32 | const add = (a: number, b: number, c: number): number => a + b + c;
33 | const curryAdd: any = utils.fn.curry(add);
34 |
35 | curryAdd(1, 2, 3); // 6
36 | curryAdd(1, 2)(4); // 7
37 | curryAdd(1)(3)(5); // 9
38 | curryAdd(1)(2, 3); // 6
39 | ```
40 |
41 | ## compose
42 | #### Describe
43 | 将传入的函数从右往左组合成新的函数。
44 | ```js
45 | (...fn: any[]) => (...params: any[]) => Return;
46 | ```
47 |
48 | #### Arguments
49 | - ...fn(any[]): 函数数组。
50 |
51 | #### Returns
52 | (```(...params: any[]) => Return```): 组合成的新函数。
53 |
54 | #### Example
55 | ```js
56 | const plusOne = (num) => num * 1 + 1;
57 | const double = (num) => num * 2;
58 | const plusOneAndDouble = utils.fn.compose(double, plusOne); // 先加一后乘二
59 |
60 | plusOneAndDouble(1); // 4
61 | plusOneAndDouble(2); // 6
62 | ```
--------------------------------------------------------------------------------
/docs/zh-cn/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Windlike-Utils
7 |
8 |
9 |
10 |
11 |
16 |
17 |
18 |
22 | Loading...
23 |
24 |
32 |
34 |
35 |
--------------------------------------------------------------------------------
/docs/zh-cn/math.md:
--------------------------------------------------------------------------------
1 | # Math
2 | ```js
3 | interface MathModule {
4 | createSin: (height: number, width: number, offset: number) => (x: number) => number;
5 | createGetPointOnCircle: (radius: number, offsetX: number, offsetY: number) => (radian: number) => Point;
6 | }
7 |
8 | interface Point {
9 | x: number;
10 | y: number;
11 | }
12 | ```
13 |
14 | ## createSin
15 | #### Describe
16 | 创建sin函数,y=f(x)=height \* sin(width \* x + offset)。
17 | ```js
18 | (height: number, width: number, offset: number) => (x: number) => number;
19 | ```
20 |
21 | #### Arguments
22 | - height(number)
23 | - width(number)
24 | - offset(number)
25 |
26 | #### Returns
27 | (```(x: number) => number```): 传入参数返回计算结果的函数。
28 |
29 | #### Example
30 | ```js
31 | const sin = utils.math.createSin(2, 2, Math.PI / 2);
32 |
33 | sin(Math.PI / 2); // -2
34 | ```
35 |
36 | ## createGetPointOnCircle
37 | #### Describe
38 | 创建获取点在圆上的位置的函数。
39 | ```js
40 | interface Point {
41 | x: number;
42 | y: number;
43 | }
44 |
45 | (radius: number, offsetX: number, offsetY: number) => (radian: number) => Point;
46 | ```
47 |
48 | #### Arguments
49 | - radius(number): 半径
50 | - offsetX(number): X轴偏移
51 | - offsetY(number): Y轴偏移
52 |
53 | #### Returns
54 | (```(radian: number) => Point```): 传入弧度返回计算结果的函数。
55 |
56 | #### Example
57 | ```js
58 | const getPointOnCircle = utils.math.createGetPointOnCircle(4, 10, 5);
59 |
60 | getPointOnCircle(0); // { x: 14, y: 5 }
61 | ```
62 |
--------------------------------------------------------------------------------
/docs/zh-cn/net.md:
--------------------------------------------------------------------------------
1 | # Net
2 | ```js
3 | interface NetModule {
4 | parseParams: (locationSearch: string) => object;
5 | parseUrl: (url: string) => UrlInfoObject;
6 | }
7 |
8 | interface UrlInfoObject {
9 | url: string
10 | host: string
11 | port: number
12 | path: string
13 | params: object
14 | }
15 | ```
16 |
17 | ## parseParams
18 | #### Describe
19 | 解析地址参数字符串为对象的函数。
20 | ```js
21 | (locationSearch: string) => object;
22 | ```
23 |
24 | #### Arguments
25 | - locationSearch(string): 参数字符串,如'?key=value&search=windlike'。
26 |
27 | #### Returns
28 | (object): 参数对象。
29 |
30 | #### Example
31 | ```js
32 | const SEARCH = '?key=value&search=windlike';
33 |
34 | utils.net.parseParams(SEARCH); // { key: 'value', search: 'windlike' }
35 | ```
36 |
37 | ## parseUrl
38 | #### Describe
39 | 解析地址的函数。
40 | ```js
41 | interface UrlInfoObject {
42 | url: string
43 | host: string
44 | port: number
45 | path: string
46 | params: object
47 | }
48 |
49 | (url: string) => UrlInfoObject;
50 | ```
51 |
52 | #### Arguments
53 | - url(string): 地址。
54 |
55 | #### Returns
56 | (UrlInfoObject): 含有地址信息的对象。
57 |
58 | #### Example
59 | ```js
60 | const URL = 'https://github.com/MrWindlike/Windlike-Utils?key=value';
61 |
62 | utils.net.parseUrl(URL);
63 | // {
64 | // url: URL,
65 | // host: 'https://github.com',
66 | // port: 80,
67 | // path: '/MrWindlike/Windlike-Utils',
68 | // params: {
69 | // key: 'value',
70 | // },
71 | // }
72 | ```
--------------------------------------------------------------------------------
/docs/zh-cn/number.md:
--------------------------------------------------------------------------------
1 | # Number
2 | ```js
3 | interface NumberModule {
4 | createRandomFunction: (min: number, max: number, float: boolean) => () => number;
5 | }
6 | ```
7 |
8 | ## createRandomFunction
9 | #### Describe
10 | 创建产生随机数函数的函数。
11 | ```js
12 | (min: number, max: number, float: boolean) => () => number;
13 | ```
14 |
15 | #### Arguments
16 | - min(number)
17 | - max(number)
18 | - float(boolean): 是否有小数
19 |
20 | #### Returns
21 | (```() => number```): 产生随机数的函数。
22 |
23 | #### Example
24 | ```js
25 | const createRandom = utils.number.createRandomFunction(100, 1, true);
26 |
27 | createRandom();
28 | ```
--------------------------------------------------------------------------------
/docs/zh-cn/object.md:
--------------------------------------------------------------------------------
1 | # Object
2 | ```js
3 | interface ObjectModule {
4 | valueEqual: (firstObj: AnyObject, secondObj: AnyObject) => boolean
5 | }
6 | ```
7 |
8 | ## valueEqual
9 | #### Describe
10 | 判断两个对象的值是否相等,会遍历子对象。
11 | ```js
12 | (firstObj: AnyObject, secondObj: AnyObject) => boolean;
13 | ```
14 |
15 | #### Arguments
16 | - firstObj(object)
17 | - secondObj(object)
18 |
19 | #### Returns
20 | (boolean)
21 |
22 | #### Example
23 | ```js
24 | utils.object.valueEqual(
25 | {
26 | a: 1,
27 | child: {
28 | key: 'value'
29 | },
30 | b: 2,
31 | obj: {},
32 | },
33 | {
34 | b: 2,
35 | obj: {},
36 | a: 1,
37 | child: {
38 | key: 'value'
39 | },
40 | },
41 | ); // true
42 | utils.object.valueEqual(
43 | {
44 | a: 1,
45 | b: 2,
46 | },
47 | {
48 | a: 1,
49 | b: '2',
50 | }
51 | ); // false
52 |
53 | ```
54 |
55 | ## has
56 | #### Describe
57 | 判断一个对象是否有该属性
58 | ```js
59 | (object: AnyObject, key: string) => boolean;
60 | ```
61 |
62 | #### Arguments
63 | - object(object)
64 | - key(string)
65 |
66 | #### Returns
67 | (boolean)
68 |
69 | #### Example
70 | ```js
71 | const object = { key: 'value', nonexistent: undefined };
72 |
73 | utils.object.has(object, 'key'); // true
74 | utils.object.has(object, 'nonexistent'); // false
75 | ```
76 |
--------------------------------------------------------------------------------
/docs/zh-cn/string.md:
--------------------------------------------------------------------------------
1 | # String
2 | ```js
3 | interface StringModule {
4 | replace: (match: RegExp | string) => (str: string, substitute: any) => string;
5 | split: (char: string | RegExp) => (str: string) => string[];
6 | match: (regexp: RegExp) => (str: string) => string[];
7 | }
8 | ```
9 |
10 | ## replace
11 | #### Describe
12 | 对原生```replace```进行封装过的函数。
13 | ```js
14 | (match: RegExp | string) => (str: string, substitute: any) => string;
15 | ```
16 |
17 | #### Arguments
18 | - match(RegExp | string): 匹配符
19 |
20 | #### Returns
21 | (```(str: string, substitute: any) => string```): 传入原字符串和代替字符串,返回新字符串的函数。
22 |
23 | #### Example
24 | ```js
25 | const str = 'I\'m Windlike.';
26 | const replaceWindlike = utils.string.replace('Windlike');
27 |
28 | replaceWindlike(str, 'I'); // I'm I.
29 | ```
30 |
31 | ## split
32 | #### Describe
33 | 对原生```split```进行封装过的函数。
34 | ```js
35 | (char: string | RegExp) => (str: string) => string[];
36 | ```
37 |
38 | #### Arguments
39 | - char(RegExp | string): 分割符
40 |
41 | #### Returns
42 | (```(str: string) => string[]```): 传入原字符串,返回分割后的数组的函数。
43 |
44 | #### Example
45 | ```js
46 | const str = 'I And You';
47 | const splitSpace = utils.string.split(' ');
48 |
49 | splitSpace(str); // ['I', 'And', 'You']
50 | ```
51 |
52 | ## match
53 | #### Describe
54 | 对原生```match```进行封装过的函数。
55 | ```js
56 | (regexp: RegExp) => (str: string) => string[];
57 | ```
58 |
59 | #### Arguments
60 | - regexp(RegExp): 正则表达式
61 |
62 | #### Returns
63 | (```(str: string) => string[]```): 传入原字符串,返回匹配到的字符串数组的函数。
64 |
65 | #### Example
66 | ```js
67 | const re = /[\w]+/g;
68 | const str = 'I am a string.';
69 | const matchWork = utils.string.match(re);
70 |
71 | matchWork(str); // ['I', 'am', 'a', 'string']
72 | ```
--------------------------------------------------------------------------------
/docs/zh-cn/verification.md:
--------------------------------------------------------------------------------
1 | # Verification
2 | ```js
3 | interface VerificationModule {
4 | readonly _phoneRE: RegExp;
5 | readonly _emailRE: RegExp;
6 |
7 | checkRe: (re: RegExp) => (checkedStr: string) => boolean;
8 | checkLength: (min: number, max: number) => (str: string) => boolean;
9 | check: (checkType: CheckType) => (checkedStr: string) => boolean;
10 | [prop: string]: any
11 | }
12 |
13 | type CheckType = 'phone' | 'email';
14 | ```
15 |
16 | ## checkRe
17 | #### Describe
18 | 创建检测字符串是否匹配正则表达式的函数。
19 | ```js
20 | (re: RegExp) => (checkedStr: string) => boolean;
21 | ```
22 |
23 | #### Arguments
24 | - re(RegExp)
25 |
26 | #### Returns
27 | (```(checkedStr: string) => boolean```): 判断是否匹配正则的函数。
28 |
29 | #### Example
30 | ```js
31 | const checkFunction = utils.verification.checkRe(/<[\s\S]*?(script)[\s\S]*?>/);
32 |
33 | checkFunction(''); // true
34 | checkFunction(''); // true
35 | checkFunction(''); // true
36 | ```
37 |
38 | ## checkLength
39 | #### Describe
40 | 创建检测字符串是否符合长度的函数。
41 | ```js
42 | (min: number, max: number) => (str: string) => boolean;
43 | ```
44 |
45 | #### Arguments
46 | - min(number)
47 | - max(number)
48 |
49 | #### Returns
50 | (```(str: string) => boolean```): 判断字符串是否符合长度的函数。
51 |
52 | #### Example
53 | ```js
54 | const checkStringLength = utils.verification.checkLength(1, 5);
55 |
56 | checkStringLength('windlike'); // false
57 | checkStringLength('wind'); // true
58 | ```
59 |
60 | ## check
61 | #### Describe
62 | 创建检测字符串是否符合响应类型的函数。
63 | ```js
64 | type CheckType = 'phone' | 'email';
65 |
66 | (checkType: CheckType) => (checkedStr: string) => boolean;
67 | ```
68 |
69 | #### Arguments
70 | - checkType(CheckType): 类型,可选:'phone'、'email'
71 |
72 | #### Returns
73 | (```(checkedStr: string) => boolean```): 判断字符串是否符合类型的函数。
74 |
75 | #### Example
76 | ```js
77 | const checkPhone = utils.verification.check('phone');
78 | const checkEmail = utils.verification.check('email');
79 |
80 | checkPhone('13800000000'); // true
81 | checkEmail('windlike@windlike.com'); // true
82 | ```
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gp = require('gulp');
2 | var concat = require('gulp-concat');
3 | var uglify = require('gulp-uglify');
4 |
5 |
6 | let scripts = [
7 | 'dist/*.js',
8 | 'dist/**/*.js',
9 | ];
10 |
11 | gp.task('build', function () {
12 | // 合并
13 | gp.src(scripts).pipe(concat('utils.js')).pipe(gp.dest('./release'));
14 |
15 | // 合并并压缩
16 | gp.src(scripts).pipe(concat('utils.min.js')).pipe(uglify()).pipe(gp.dest('./release'));
17 | });
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const utils = require('./dist/utils');
2 |
3 | module.exports = utils;
4 | module.exports.default = utils;
5 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "windlike-utils",
3 | "version": "2.1.6",
4 | "description": "Windlike-Utils is a tool library developed based on functional programming ideas.",
5 | "sideEffects": false,
6 | "main": "./dist/utils.js",
7 | "scripts": {
8 | "test": "jest",
9 | "debug": "node --inspect-brk node_modules/jest/bin/jest.js --runInBand",
10 | "dev": "tsc -w --downlevelIteration",
11 | "start": "node index",
12 | "build": "tsc -d && gulp build",
13 | "lint": "eslint src --ext .ts",
14 | "lint:fix": "eslint src --ext .ts --fix",
15 | "log": "conventional-changelog -p angular -i CHANGELOG.md -w -r 0",
16 | "prepublish": "yarn test && yarn build"
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "git+https://github.com/MrWindlike/Windlike-Utils.git"
21 | },
22 | "keywords": [
23 | "utils",
24 | "tool"
25 | ],
26 | "author": "Windlike",
27 | "license": "ISC",
28 | "bugs": {
29 | "url": "https://github.com/MrWindlike/Windlike-Utils/issues"
30 | },
31 | "homepage": "https://github.com/MrWindlike/Windlike-Utils#readme",
32 | "devDependencies": {
33 | "@types/jest": "^23.3.0",
34 | "awesome-typescript-loader": "^3.4.0",
35 | "babel-core": "^6.26.0",
36 | "babel-loader": "^7.1.2",
37 | "babel-plugin-transform-runtime": "^6.23.0",
38 | "babel-preset-es2015": "^6.24.1",
39 | "babel-runtime": "^6.26.0",
40 | "cz-conventional-changelog": "^2.1.0",
41 | "eslint": "^5.2.0",
42 | "eslint-plugin-typescript": "^0.12.0",
43 | "ghooks": "^2.0.4",
44 | "gulp": "^3.9.1",
45 | "gulp-concat": "^2.6.1",
46 | "gulp-uglify": "^3.0.0",
47 | "jest": "^23.4.1",
48 | "source-map-loader": "^0.2.3",
49 | "ts-jest": "^23.0.1",
50 | "typescript": "^2.6.2",
51 | "typescript-eslint-parser": "^17.0.1",
52 | "validate-commit-msg": "^2.14.0"
53 | },
54 | "jest": {
55 | "roots": [
56 | "/src"
57 | ],
58 | "transform": {
59 | "^.+\\.tsx?$": "ts-jest"
60 | },
61 | "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
62 | "moduleFileExtensions": [
63 | "ts",
64 | "tsx",
65 | "js",
66 | "jsx",
67 | "json",
68 | "node"
69 | ]
70 | },
71 | "config": {
72 | "commitizen": {
73 | "path": "./node_modules/cz-conventional-changelog"
74 | },
75 | "ghooks": {
76 | "pre-commit": "yarn run eslint && yarn test",
77 | "commit-msg": "validate-commit-msg"
78 | }
79 | }
80 | }
--------------------------------------------------------------------------------
/release/utils.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | ///
3 | Object.defineProperty(exports, "__esModule", { value: true });
4 | var index_1 = require("./array/index");
5 | exports.array = index_1.default;
6 | var index_2 = require("./date/index");
7 | exports.date = index_2.default;
8 | var index_3 = require("./fn/index");
9 | exports.fn = index_3.default;
10 | var index_4 = require("./math/index");
11 | exports.math = index_4.default;
12 | var index_5 = require("./number/index");
13 | exports.number = index_5.default;
14 | var index_6 = require("./net/index");
15 | exports.net = index_6.default;
16 | var index_7 = require("./object/index");
17 | exports.object = index_7.default;
18 | var index_8 = require("./string/index");
19 | exports.string = index_8.default;
20 | var index_9 = require("./verification/index");
21 | exports.verification = index_9.default;
22 | /**
23 | * @obj
24 | * @desc 工具实例。部分函数使用到ES6的语法,请确保你的浏览器支持。
25 | * @part array - 数组
26 | * @part date - 日期
27 | * @part fn - 函数
28 | * @part math - 数学
29 | * @part number - 数字
30 | * @part net - 网络
31 | * @part object - 对象
32 | * @part string - 字符串
33 | * @part verification - 验证
34 | */
35 | exports.utils = { array: index_1.default, date: index_2.default, fn: index_3.default, math: index_4.default, number: index_5.default, net: index_6.default, object: index_7.default, string: index_8.default, verification: index_9.default };
36 | exports.default = exports.utils;
37 | //# sourceMappingURL=utils.js.map
38 | "use strict";
39 | ///
40 | Object.defineProperty(exports, "__esModule", { value: true });
41 | var index_1 = require("../object/index");
42 | var _this = null;
43 | var array = _this = {
44 | /* 比较相关函数 */
45 | /**
46 | * @func
47 | * @desc 比较两个数组的长度
48 | * @return 0 - 相等
49 | * @return >0 - 第一个大于第二个的长度
50 | * @return <0 - 第一个小于第二个的长度
51 | */
52 | compareLength: function (firstArray, secondArray) {
53 | return firstArray.length - secondArray.length;
54 | },
55 | shallowCompare: function (firstArray, secondArray) {
56 | return index_1.shallowCompare(firstArray, secondArray);
57 | },
58 | deepCompare: function (firstArray, secondArray) {
59 | return index_1.deepCompare(firstArray, secondArray);
60 | },
61 | /* 删除相关函数 */
62 | deleteItem: function (array, value) {
63 | var tempArray = array.slice();
64 | var index = tempArray.indexOf(value);
65 | if (index !== -1) {
66 | tempArray.splice(index, 1);
67 | }
68 | return tempArray;
69 | },
70 | deleteItems: function (array, value) {
71 | return array.filter(function (item) { return item !== value; });
72 | },
73 | deleteItemsExcept: function (array, exceptArray) {
74 | return array.filter(function (value) { return exceptArray.includes(value); });
75 | },
76 | /* 原生封装 */
77 | map: function (fn) {
78 | return function (array) { return array.map(fn); };
79 | }
80 | };
81 | exports.default = array;
82 | exports.compareLength = array.compareLength;
83 | exports.shallowCompare = array.shallowCompare;
84 | exports.deepCompare = array.deepCompare;
85 | exports.deleteItem = array.deleteItem;
86 | exports.deleteItems = array.deleteItems;
87 | exports.deleteItemsExcept = array.deleteItemsExcept;
88 | exports.map = array.map;
89 | //# sourceMappingURL=index.js.map
90 | "use strict";
91 | Object.defineProperty(exports, "__esModule", { value: true });
92 | ///
93 | var index_1 = require("../string/index");
94 | /**
95 | * @obj
96 | * @desc 操作日期的相关方法。所有函数不会改变实参的值,会返回操作后的结果。
97 | * @method createFormatDate - 传入日期格式,返回已毫秒数做参数的日期格式化函数。详情见本函数。
98 | */
99 | var date = {
100 | /**
101 | * @func
102 | * @desc 格式化日期的函数。
103 | * @param {string} format - 需要的日期的格式。如:
104 | 'yy-MM-dd hh:mm:ss ww'(ww为星期,小写w为英文,大写W为中文)
105 | 'MM dd,yyyy hh:mm:ss'等等
106 | * @return {function} 返回一个需要传入毫秒数作为参数的函数。
107 | */
108 | createFormatDate: function (format) {
109 | if (format === void 0) { format = 'YYYY/MM/DD hh:mm'; }
110 | var replaceFormat = index_1.replace(/[a-zA-Z]+/g);
111 | return function (ms) {
112 | var dateFunctions = {
113 | 'Y': 'getFullYear',
114 | 'M': 'getMonth',
115 | 'D': 'getDate',
116 | 'h': 'getHours',
117 | 'm': 'getMinutes',
118 | 's': 'getSeconds',
119 | 'w': 'getDay',
120 | 'W': 'getDay'
121 | };
122 | var weeks = {
123 | 'w': ['Sun.', 'Mon.', 'Tues.', 'Wed.', 'Thur.', 'Fri.', 'Sat.'],
124 | 'W': ['日', '一', '二', '三', '四', '五', '六'].map(function (week) { return "\u661F\u671F" + week; })
125 | };
126 | var date = new Date(ms);
127 | return replaceFormat(format, function (matchStr) {
128 | var dateFuncName = dateFunctions[matchStr[0]];
129 | if (dateFuncName) {
130 | if (dateFuncName === 'getMonth') {
131 | var str = "0000" + (date[dateFuncName]() + 1);
132 | return str.substring(str.length - matchStr.length);
133 | }
134 | else if (dateFuncName === 'getDay') {
135 | return weeks[matchStr[0]][date[dateFuncName]()];
136 | }
137 | else {
138 | var str = '0000' + date[dateFuncName]();
139 | return str.substring(str.length - matchStr.length);
140 | }
141 | }
142 | else {
143 | return matchStr;
144 | }
145 | });
146 | };
147 | }
148 | };
149 | exports.default = date;
150 | exports.createFormatDate = date.createFormatDate;
151 | //# sourceMappingURL=index.js.map
152 | "use strict";
153 | ///
154 | Object.defineProperty(exports, "__esModule", { value: true });
155 | /**
156 | * @obj
157 | * @desc 操作函数的相关方法。所有函数不会改变实参的值,会返回操作后的结果。
158 | * @method curry - 将传入的函数柯里化
159 | * @method compose - 将所有传入的函数从右向左组合起来
160 | */
161 | var fn = {
162 | curry: function (fn) {
163 | var paramsLength = fn.length;
164 | function closure(params) {
165 | var wrapper = function () {
166 | var newParams = [];
167 | for (var _i = 0; _i < arguments.length; _i++) {
168 | newParams[_i] = arguments[_i];
169 | }
170 | var allParams = params.concat(newParams);
171 | if (allParams.length < paramsLength) {
172 | return closure(allParams);
173 | }
174 | else {
175 | return fn.apply(null, allParams);
176 | }
177 | };
178 | return wrapper;
179 | }
180 | return closure([]);
181 | },
182 | compose: function () {
183 | var fn = [];
184 | for (var _i = 0; _i < arguments.length; _i++) {
185 | fn[_i] = arguments[_i];
186 | }
187 | return function () {
188 | var params = [];
189 | for (var _i = 0; _i < arguments.length; _i++) {
190 | params[_i] = arguments[_i];
191 | }
192 | var i = fn.length - 1;
193 | var result = fn[i].apply(null, params);
194 | while (--i >= 0) {
195 | result = fn[i](result);
196 | }
197 | return result;
198 | };
199 | },
200 | debounce: function (fn, wait, immediate) {
201 | var now = Date.now.bind(Date);
202 | var lastTime = 0;
203 | var timer = null;
204 | var params = null;
205 | var _this = null;
206 | function later() {
207 | var nowTime = now();
208 | if (nowTime - lastTime < wait) {
209 | var remainTime = wait - (nowTime - lastTime);
210 | timer = setTimeout(later, remainTime);
211 | }
212 | else {
213 | debouncer.result = fn.apply(_this, params);
214 | timer = null;
215 | _this = null;
216 | params = null;
217 | }
218 | }
219 | function execute() {
220 | lastTime = now();
221 | _this = this;
222 | params = arguments;
223 | try {
224 | if (immediate && timer === null) {
225 | debouncer.result = fn.apply(_this, params);
226 | }
227 | return debouncer.result;
228 | }
229 | finally {
230 | if (timer === null) {
231 | timer = setTimeout(later, wait);
232 | }
233 | }
234 | }
235 | var debouncer = {
236 | execute: execute,
237 | result: null,
238 | };
239 | return debouncer;
240 | },
241 | throttle: function (fn, wait, _a) {
242 | var _b = _a === void 0 ? {
243 | isExecuteAtStart: true,
244 | isExecuteAtEnd: true,
245 | } : _a, _c = _b.isExecuteAtStart, isExecuteAtStart = _c === void 0 ? true : _c, _d = _b.isExecuteAtEnd, isExecuteAtEnd = _d === void 0 ? true : _d;
246 | var timer = null;
247 | var _this = null;
248 | var params = null;
249 | function execute() {
250 | _this = this;
251 | params = arguments;
252 | if (isExecuteAtStart && timer === null) {
253 | executor.result = fn.apply(_this, params);
254 | _this = null;
255 | params = null;
256 | }
257 | if (isExecuteAtEnd) {
258 | if (timer === null) {
259 | timer = setTimeout(function () {
260 | executor.result = fn.apply(_this, params);
261 | _this = null;
262 | params = null;
263 | timer = null;
264 | }, wait);
265 | }
266 | }
267 | return executor.result;
268 | }
269 | var executor = {
270 | execute: execute,
271 | result: null
272 | };
273 | return executor;
274 | }
275 | };
276 | exports.default = fn;
277 | exports.curry = fn.curry;
278 | exports.compose = fn.compose;
279 | exports.debounce = fn.debounce;
280 | exports.throttle = fn.throttle;
281 | //# sourceMappingURL=index.js.map
282 | "use strict";
283 | ///
284 | Object.defineProperty(exports, "__esModule", { value: true });
285 | var math = {
286 | createSin: function (height, width, offset) {
287 | return function (x) { return height * Math.sin(width * x + offset); };
288 | },
289 | createGetPointOnCircle: function (radius, offsetX, offsetY) {
290 | if (offsetX === void 0) { offsetX = 0; }
291 | if (offsetY === void 0) { offsetY = 0; }
292 | return function (radian) { return ({
293 | x: offsetX + radius * Math.cos(radian),
294 | y: offsetY + radius * Math.sin(radian),
295 | }); };
296 | },
297 | add: function () {
298 | var numbers = [];
299 | for (var _i = 0; _i < arguments.length; _i++) {
300 | numbers[_i] = arguments[_i];
301 | }
302 | function getDecimalLength(n) {
303 | var temp = n.toString().split('.');
304 | return temp[temp.length - 1].length;
305 | }
306 | function addTwoNumber(a, b) {
307 | var firstLenth = getDecimalLength(a);
308 | var secondeLenth = getDecimalLength(a);
309 | var biggerLength = firstLenth > secondeLenth ? firstLenth : secondeLenth;
310 | var n = Math.pow(10, biggerLength);
311 | return (a * n + b * n) / n;
312 | }
313 | return numbers.reduce(function (previous, current) {
314 | return addTwoNumber(previous, current);
315 | });
316 | },
317 | };
318 | exports.default = math;
319 | exports.createSin = math.createSin;
320 | exports.createGetPointOnCircle = math.createGetPointOnCircle;
321 | exports.add = math.add;
322 | //# sourceMappingURL=index.js.map
323 | "use strict";
324 | ///
325 | Object.defineProperty(exports, "__esModule", { value: true });
326 | var index_1 = require("../string/index");
327 | var index_2 = require("../array/index");
328 | var index_3 = require("../fn/index");
329 | /**
330 | * @obj
331 | * @desc desc
332 | * @method parseParams - 解析URL的参数部分的函数
333 | * @method parseUrl - 解析URL的函数
334 | */
335 | var net = {
336 | parseParams: function (locationSearch) {
337 | var first = function (arr) { return arr[0]; };
338 | var last = function (arr) { return arr[arr.length - 1]; };
339 | var hasQuestionMark = function (locationSearch) { return locationSearch.includes('?') ? locationSearch : "?" + locationSearch; };
340 | var separateOutParams = index_3.default.compose(last, index_1.default.split('?'), hasQuestionMark);
341 | var groupingParams = index_3.default.compose(index_2.default.map(index_1.default.split('=')), index_1.default.split('&'));
342 | var getParams = function (paramsArr) {
343 | var params = {};
344 | paramsArr.forEach(function (param) {
345 | if (first(param)) {
346 | params[first(param)] = last(param);
347 | }
348 | });
349 | return params;
350 | };
351 | var paramsStr = separateOutParams(locationSearch);
352 | var paramsArr = groupingParams(paramsStr);
353 | var params = getParams(paramsArr);
354 | return params;
355 | },
356 | parseUrl: function (url) {
357 | var HOST_PORT_REGEXP = /^(http:\/\/|https:\/\/)[0-9a-zA-Z.:]+/;
358 | var HOST_REGEXP = /^(http:\/\/|https:\/\/)[0-9a-zA-Z.]+/;
359 | /* function */
360 | var first = function (arr) { return arr[0]; };
361 | var last = function (arr) { return arr[arr.length - 1]; };
362 | var checkPort = function (port) { return port ? port : 80; };
363 | var checkPath = function (path) { return path ? path : '/'; };
364 | var checkParams = function (url) { return url.includes('?') ? url : ''; };
365 | var separateOutHref = index_3.default.compose(first, index_1.default.split('?'));
366 | var separateOutParams = index_3.default.compose(last, index_1.default.split('?'), checkParams);
367 | var matchHost = index_3.default.compose(first, index_1.default.match(HOST_PORT_REGEXP));
368 | var groupingParams = index_3.default.compose(index_2.default.map(index_1.default.split('=')), index_1.default.split('&'));
369 | var getParams = function (paramsArr) {
370 | var params = {};
371 | paramsArr.forEach(function (param) {
372 | if (first(param)) {
373 | params[first(param)] = last(param);
374 | }
375 | });
376 | return params;
377 | };
378 | var getHost = index_3.default.compose(first, index_1.default.match(HOST_REGEXP));
379 | var getPort = function (host) { return index_3.default.compose(checkPort, last, index_1.default.split(':'), last, index_1.default.split(host)); };
380 | /* var */
381 | var href = separateOutHref(url);
382 | var paramsStr = separateOutParams(url);
383 | var hostWithPort = matchHost(href);
384 | var host = getHost(hostWithPort);
385 | var port = getPort(host)(hostWithPort);
386 | var path = index_3.default.compose(checkPath, last, index_1.default.split(hostWithPort))(href);
387 | var paramsArr = groupingParams(paramsStr);
388 | var params = getParams(paramsArr);
389 | var urlMsg = { url: url, host: host, port: port, path: path, params: params };
390 | return urlMsg;
391 | }
392 | };
393 | exports.default = net;
394 | exports.parseParams = net.parseParams;
395 | exports.parseUrl = net.parseUrl;
396 | //# sourceMappingURL=index.js.map
397 | "use strict";
398 | ///
399 | Object.defineProperty(exports, "__esModule", { value: true });
400 | /**
401 | * @obj
402 | * @desc 数字的相关方法。所有函数不会改变实参的值,会返回操作后的结果。
403 | * @method random - 返回一个可以产生符合条件的随机数的函数
404 | */
405 | var number = {
406 | createRandomFunction: function (min, max, float) {
407 | if (min === void 0) { min = 0; }
408 | return function () {
409 | var _a;
410 | if (min > max) {
411 | _a = [max, min], min = _a[0], max = _a[1];
412 | }
413 | if (float || min % 1 || max % 1) {
414 | return min + Math.random() * (max - min);
415 | }
416 | return min + Math.floor(Math.random() * (max - min + 1));
417 | };
418 | }
419 | };
420 | exports.default = number;
421 | exports.createRandomFunction = number.createRandomFunction;
422 | //# sourceMappingURL=index.js.map
423 | "use strict";
424 | Object.defineProperty(exports, "__esModule", { value: true });
425 | ///
426 | /**
427 | * @obj
428 | * @desc 操作对象的相关方法。所有函数不会改变实参的值,会返回操作后的结果。
429 | * @method valueEqual - 判断两个对象的值是否相等
430 | */
431 | var _this = null;
432 | var object = (_this = {
433 | shallowCompare: function (firstObj, secondObj) {
434 | for (var key in firstObj) {
435 | if (!firstObj.hasOwnProperty(key) ||
436 | !secondObj.hasOwnProperty(key) ||
437 | firstObj[key] !== secondObj[key]) {
438 | return false;
439 | }
440 | }
441 | return true;
442 | },
443 | deepCompare: function (firstObj, secondObj) {
444 | var firstEntries = Object.entries(firstObj);
445 | var secondEntries = Object.entries(secondObj);
446 | if (firstEntries.length !== secondEntries.length) {
447 | return false;
448 | }
449 | for (var _i = 0, firstEntries_1 = firstEntries; _i < firstEntries_1.length; _i++) {
450 | var key = firstEntries_1[_i][0];
451 | var firstValue = firstObj[key];
452 | var secondValue = secondObj[key];
453 | if (typeof firstValue !== typeof secondValue) {
454 | return false;
455 | }
456 | else if (typeof firstValue === 'object' && firstValue !== null) {
457 | if (!_this.deepCompare(firstValue, secondValue)) {
458 | return false;
459 | }
460 | }
461 | else {
462 | if (firstValue !== secondValue) {
463 | return false;
464 | }
465 | }
466 | }
467 | return true;
468 | },
469 | has: function (object, key) {
470 | return object[key] !== undefined;
471 | }
472 | });
473 | exports.default = object;
474 | exports.shallowCompare = object.shallowCompare;
475 | exports.deepCompare = object.deepCompare;
476 | exports.has = object.has;
477 | //# sourceMappingURL=index.js.map
478 | "use strict";
479 | ///
480 | Object.defineProperty(exports, "__esModule", { value: true });
481 | /**
482 | * @obj
483 | * @desc 操作字符串的相关方法。所有函数不会改变实参的值,会返回操作后的结果。
484 | * @method replace - 传入匹配规则参数,返回一个符合改匹配规则的函数
485 | * @method split - 返回分割该字符的函数
486 | * @method match - 返回匹配该正则的函数
487 | */
488 | var _this = null;
489 | exports.string = _this = {
490 | replace: function (match) {
491 | return function (str, substitute) { return str.replace(match, substitute); };
492 | },
493 | split: function (char) {
494 | return function (str) { return str.split(char); };
495 | },
496 | match: function (regexp) {
497 | return function (str) { return str.match(regexp); };
498 | }
499 | };
500 | exports.default = exports.string;
501 | exports.replace = exports.string.replace;
502 | exports.split = exports.string.split;
503 | exports.match = exports.string.match;
504 | //# sourceMappingURL=index.js.map
505 | "use strict";
506 | ///
507 | Object.defineProperty(exports, "__esModule", { value: true });
508 | /**
509 | * @obj
510 | * @desc 验证的相关方法。所有函数不会改变实参的值,会返回操作后的结果。
511 | * @method checkRe - 返回验证是否匹配该正则的函数
512 | * @method checkLength - 返回验证是否匹配长度的函数
513 | * @method check - 返回验证是否匹配该类型的函数
514 | */
515 | var _this = null;
516 | exports.verification = _this = {
517 | _phoneRE: /^(13[0-9]|15[012356789]|18[0-9]|17[678]|14[57])[0-9]{8}$/,
518 | _emailRE: /^([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/,
519 | checkRe: function (re) {
520 | return function (checkedStr) {
521 | return re.test(checkedStr);
522 | };
523 | },
524 | checkLength: function (min, max) {
525 | if (min === void 0) { min = 0; }
526 | return function (str) { return str.length >= min && str.length <= max; };
527 | },
528 | check: function (checkType) {
529 | return _this.checkRe(_this["_" + checkType + "RE"]);
530 | }
531 | };
532 | exports.default = exports.verification;
533 | exports.checkRe = exports.verification.checkRe;
534 | exports.checkLength = exports.verification.checkLength;
535 | exports.check = exports.verification.check;
536 | //# sourceMappingURL=index.js.map
--------------------------------------------------------------------------------
/release/utils.min.js:
--------------------------------------------------------------------------------
1 | "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var index_1=require("./array/index");exports.array=index_1.default;var index_2=require("./date/index");exports.date=index_2.default;var index_3=require("./fn/index");exports.fn=index_3.default;var index_4=require("./math/index");exports.math=index_4.default;var index_5=require("./number/index");exports.number=index_5.default;var index_6=require("./net/index");exports.net=index_6.default;var index_7=require("./object/index");exports.object=index_7.default;var index_8=require("./string/index");exports.string=index_8.default;var index_9=require("./verification/index");exports.verification=index_9.default,exports.utils={array:index_1.default,date:index_2.default,fn:index_3.default,math:index_4.default,number:index_5.default,net:index_6.default,object:index_7.default,string:index_8.default,verification:index_9.default},exports.default=exports.utils,Object.defineProperty(exports,"__esModule",{value:!0});index_1=require("../object/index");var _this=null,array=_this={compareLength:function(e,t){return e.length-t.length},shallowCompare:function(e,t){return index_1.shallowCompare(e,t)},deepCompare:function(e,t){return index_1.deepCompare(e,t)},deleteItem:function(e,t){var r=e.slice(),n=r.indexOf(t);return-1!==n&&r.splice(n,1),r},deleteItems:function(e,t){return e.filter(function(e){return e!==t})},deleteItemsExcept:function(e,t){return e.filter(function(e){return t.includes(e)})},map:function(t){return function(e){return e.map(t)}}};exports.default=array,exports.compareLength=array.compareLength,exports.shallowCompare=array.shallowCompare,exports.deepCompare=array.deepCompare,exports.deleteItem=array.deleteItem,exports.deleteItems=array.deleteItems,exports.deleteItemsExcept=array.deleteItemsExcept,exports.map=array.map,Object.defineProperty(exports,"__esModule",{value:!0});index_1=require("../string/index");var date={createFormatDate:function(t){void 0===t&&(t="YYYY/MM/DD hh:mm");var r=index_1.replace(/[a-zA-Z]+/g);return function(e){var n={Y:"getFullYear",M:"getMonth",D:"getDate",h:"getHours",m:"getMinutes",s:"getSeconds",w:"getDay",W:"getDay"},a={w:["Sun.","Mon.","Tues.","Wed.","Thur.","Fri.","Sat."],W:["日","一","二","三","四","五","六"].map(function(e){return"星期"+e})},i=new Date(e);return r(t,function(e){var t,r=n[e[0]];return r?"getMonth"!==r?"getDay"===r?a[e[0]][i[r]()]:(t="0000"+i[r]()).substring(t.length-e.length):(t="0000"+(i[r]()+1)).substring(t.length-e.length):e})}}};exports.default=date,exports.createFormatDate=date.createFormatDate,Object.defineProperty(exports,"__esModule",{value:!0});var fn={curry:function(i){var o=i.length;return function n(a){return function(){for(var e=[],t=0;t=t&&e.length<=r}},check:function(e){return _this.checkRe(_this["_"+e+"RE"])}},exports.default=exports.verification,exports.checkRe=exports.verification.checkRe,exports.checkLength=exports.verification.checkLength,exports.check=exports.verification.check;
--------------------------------------------------------------------------------
/src/__test__/import.test.ts:
--------------------------------------------------------------------------------
1 | import utils from '../../dist/utils';
2 | import { shallowCompare } from '../../dist/object';
3 |
4 | test('Import utils.', () => {
5 | expect(utils).not.toBeUndefined();
6 | expect(shallowCompare).not.toBeUndefined();
7 | });
8 |
--------------------------------------------------------------------------------
/src/__test__/require.test.ts:
--------------------------------------------------------------------------------
1 | const utils = require('../../index');
2 |
3 | test('Require utils.', () => {
4 | expect(utils).not.toBeUndefined();
5 | });
--------------------------------------------------------------------------------
/src/array/__test__/index.test.ts:
--------------------------------------------------------------------------------
1 | import {
2 | compareLength,
3 | shallowCompare,
4 | deepCompare,
5 | deleteItem,
6 | deleteItems,
7 | deleteItemsExcept,
8 | map,
9 | } from '../index';
10 |
11 | describe('Compare Array\'s length.', () => {
12 | test('Equal', () => {
13 | const firstArray = [1, 2, 3, {}];
14 | const secondArray = [{}, 3, 2, 1];
15 | const result: number = compareLength(firstArray, secondArray);
16 |
17 | expect(result).toBe(0);
18 | });
19 |
20 | test('Less than.', () => {
21 | const firstArray = [1, 2, 3];
22 | const secondArray = [{}, 3, 2, 1];
23 | const result: number = compareLength(firstArray, secondArray);
24 |
25 | expect(result).toBeLessThan(0);
26 | });
27 |
28 | test('Great than.', () => {
29 | const firstArray = [1, 2, 3, {}];
30 | const secondArray = [3, 2, 1];
31 | const result: number = compareLength(firstArray, secondArray);
32 |
33 | expect(result).toBeGreaterThan(0);
34 | });
35 | });
36 |
37 | describe('Shallow compare.Is them Equal?', () => {
38 | test('Yes.', () => {
39 | expect(shallowCompare([1, 2, 3], [1, 2, 3])).toBeTruthy();
40 | });
41 |
42 | test('No.', () => {
43 | expect(shallowCompare([1, 2, 3], [1, '2', 3])).toBeFalsy();
44 | expect(shallowCompare([1, [2, 3], 4], [1, [2, 3], 4])).toBeFalsy();
45 | expect(shallowCompare([1, 2, { key: 'value' }], [1, 2, { key: 'value' }])).toBeFalsy();
46 | });
47 | });
48 |
49 | describe('Deep compare.Is them Equal?', () => {
50 | test('Yes.', () => {
51 | expect(deepCompare([1, 2, 3], [1, 2, 3])).toBeTruthy();
52 | expect(deepCompare([1, [2, 3], 4], [1, [2, 3], 4])).toBeTruthy();
53 | expect(deepCompare([1, 2, { key: 'value' }], [1, 2, { key: 'value' }])).toBeTruthy();
54 | });
55 |
56 | test('No.', () => {
57 | expect(deepCompare([1, 2, 3], [1, '2', 3])).toBeFalsy();
58 | expect(deepCompare([1, 2, 3], [1, 3])).toBeFalsy();
59 | });
60 | });
61 |
62 | describe('Delete one item from Array where value is strict equal.', () => {
63 | test('Number Array.', () => {
64 | const array = [1, 2, 3];
65 |
66 | expect(shallowCompare(deleteItem(array, 2), [1, 3])).toBeTruthy();
67 | expect(shallowCompare(array, [1, 2, 3])).toBeTruthy();
68 | });
69 |
70 | test('Object Array.', () => {
71 | const array = [{ key: 'value' }];
72 |
73 | expect(deleteItem(array, { key: 'value' }).length).toBe(array.length);
74 | });
75 |
76 | test('Mixing Array.', () => {
77 | const array = [1, '2', '3'];
78 |
79 | expect(shallowCompare(deleteItem(array, '2'), [1, '3'])).toBeTruthy();
80 | expect(shallowCompare(array, [1, '2', '3'])).toBeTruthy();
81 | });
82 | });
83 |
84 | describe('Delete items where value is strict equal.', () => {
85 | test('Number Array', () => {
86 | const array = [1, 9, 9, 6];
87 |
88 | expect(shallowCompare(deleteItems(array, 9), [1, 6])).toBeTruthy();
89 | expect(shallowCompare(array, [1, 9, 9, 6])).toBeTruthy();
90 | });
91 |
92 | test('Object Array', () => {
93 | const array = [{}, { key: 'value' }];
94 |
95 | expect(deleteItems(array, {}).length).toBe(array.length);
96 | });
97 |
98 | test('Mixing Array', () => {
99 | const array = [1, '9', 9, 6];
100 |
101 | expect(shallowCompare(deleteItems(array, 9), [1, '9', 6])).toBeTruthy();
102 | expect(shallowCompare(array, [1, '9', 9, 6])).toBeTruthy();
103 | });
104 | });
105 |
106 | describe('Delete items expect value equal another Array.', () => {
107 | test('Number Array.', () => {
108 | const array = [1, 9, 9, 6];
109 |
110 | expect(shallowCompare(deleteItemsExcept(array, [1, 2, 3]), [1])).toBeTruthy();
111 | expect(shallowCompare(deleteItemsExcept(array, [1, 9, 3]), [1, 9, 9])).toBeTruthy();
112 | expect(shallowCompare(deleteItemsExcept(array, [1, 9, 6]), [1, 9, 9, 6])).toBeTruthy();
113 | });
114 |
115 | test('Mixing Array.', () => {
116 | const array = [1, '9', 9, 6];
117 |
118 | expect(shallowCompare(deleteItemsExcept(array, [1, 2, 3]), [1])).toBeTruthy();
119 | expect(shallowCompare(deleteItemsExcept(array, [1, 9, 3]), [1, 9])).toBeTruthy();
120 | expect(shallowCompare(deleteItemsExcept(array, [1, 9, 6]), [1, 9, 6])).toBeTruthy();
121 | expect(shallowCompare(deleteItemsExcept(array, [1, '9', 9, 6]), [1, '9', 9, 6])).toBeTruthy();
122 | });
123 | });
124 |
125 | describe('Map Array.', () => {
126 | const plusOne = (value) => 1 + value;
127 |
128 | test('Number Array.', () => {
129 | const array = [1, 9, 9, 6];
130 |
131 | expect(shallowCompare(map(plusOne)(array), [2, 10, 10, 7])).toBeTruthy();
132 | });
133 |
134 | test('Mixing Array.', () => {
135 | const array = [1, '9', 9, 6];
136 |
137 | expect(shallowCompare(map(plusOne)(array), [2, '19', 10, 7])).toBeTruthy();
138 | });
139 | });
--------------------------------------------------------------------------------
/src/array/index.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @obj
3 | * @desc 操作数组的相关方法。所有函数不会改变实参,会返回操作后的结果。
4 | * @method compareLength - 比较两个数组的长度
5 | * @method shallowCompare - 浅比较
6 | * @method deepCompare - 深比较
7 | * @method deleteValue - 从数组里删除第一个相应值,返回新数组
8 | * @method deleteValueAll - 从数组里删除所有相应值,返回新数组
9 | * @method deleteSomeExcept - 从数组里删除所有不匹配元素,返回新数组
10 | * @method map - 封装原生map
11 | */
12 | interface ArrayModule {
13 | compareLength: (firstArray: any[], secondArray: any[]) => number;
14 | shallowCompare: (firstArray: T[], secondArray: T[]) => boolean;
15 | deepCompare: (firstArray: T[], secondArray: T[]) => boolean;
16 | deleteItem: (array: T[], value: T) => T[];
17 | deleteItems: (array: T[], value: T) => T[];
18 | deleteItemsExcept: (array: T[], exceptArray: T[]) => T[];
19 | map: (fn: any) => (array: T[]) => T[];
20 | }
21 |
--------------------------------------------------------------------------------
/src/array/index.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | import {
4 | shallowCompare as objectShallowCompare,
5 | deepCompare as objectDeepCompare,
6 | } from '../object/index';
7 |
8 | let _this: ArrayModule = null;
9 | const array: ArrayModule = _this = {
10 | /* 比较相关函数 */
11 | /**
12 | * @func
13 | * @desc 比较两个数组的长度
14 | * @return 0 - 相等
15 | * @return >0 - 第一个大于第二个的长度
16 | * @return <0 - 第一个小于第二个的长度
17 | */
18 | compareLength: function (firstArray: any[], secondArray: any[]): number {
19 | return firstArray.length - secondArray.length;
20 | },
21 | shallowCompare: function (firstArray: T[], secondArray: T[]): boolean {
22 | return objectShallowCompare(firstArray, secondArray);
23 | },
24 | deepCompare: function (firstArray: T[], secondArray: T[]): boolean {
25 | return objectDeepCompare(firstArray, secondArray);
26 | },
27 |
28 | /* 删除相关函数 */
29 | deleteItem: function (array: T[], value: T): T[] {
30 | let tempArray = [...array];
31 | let index = tempArray.indexOf(value);
32 |
33 | if (index !== -1) {
34 | tempArray.splice(index, 1);
35 | }
36 |
37 | return tempArray;
38 | },
39 | deleteItems: function (array: T[], value: T): T[] {
40 | return array.filter((item) => item !== value);
41 | },
42 | deleteItemsExcept: function (array: T[], exceptArray: T[]): T[] {
43 | return array.filter(value => exceptArray.includes(value));
44 | },
45 | /* 原生封装 */
46 | map: function (fn: any): (array: T[]) => T[] {
47 | return (array: T[]) => array.map(fn);
48 | }
49 | };
50 |
51 | export default array;
52 | export const compareLength = array.compareLength;
53 | export const shallowCompare = array.shallowCompare;
54 | export const deepCompare = array.deepCompare;
55 | export const deleteItem = array.deleteItem;
56 | export const deleteItems = array.deleteItems;
57 | export const deleteItemsExcept = array.deleteItemsExcept;
58 | export const map = array.map;
59 |
--------------------------------------------------------------------------------
/src/date/__test__/index.test.ts:
--------------------------------------------------------------------------------
1 | import date from '../index';
2 | const {
3 | createFormatDate,
4 | } = date;
5 |
6 | describe('Format date.', () => {
7 | const ms = 837043200000; // 1996-07-11 08:00:00
8 |
9 | test('YYYY-MM-DD.', () => {
10 | expect(createFormatDate('YYYY-MM-DD')(ms)).toBe('1996-07-11');
11 | });
12 |
13 | test('YYYY-MM-DD hh:mm:ss w.', () => {
14 | expect(createFormatDate('YYYY-MM-DD hh:mm:ss w')(ms)).toBe('1996-07-11 08:00:00 Thur.');
15 | });
16 |
17 | test('YYYY-MM-DD hh:mm:ss W.', () => {
18 | expect(createFormatDate('YY-MM-DD hh:mm:ss W')(ms)).toBe('96-07-11 08:00:00 星期四');
19 | });
20 | });
--------------------------------------------------------------------------------
/src/date/index.d.ts:
--------------------------------------------------------------------------------
1 | interface DateModule {
2 | /**
3 | * @func
4 | * @desc 格式化日期的函数。
5 | * @param {string} createFormatDate - 需要的日期的格式。如:
6 | 'YYYY-MM-DD hh:mm:ss ww'(ww为星期,小写w为英文,大写W为中文)
7 | 'MM dd,YYYY hh:mm:ss'等等
8 | * @return {function} 返回一个需要传入毫秒数作为参数的函数。
9 | */
10 | createFormatDate: (format: string) => (date: number) => string;
11 | }
12 |
13 | type DateFnName = 'getFullYear' | 'getMonth' | 'getDate' | 'getHours' | 'getMinutes' | 'getSeconds' | 'getDay';
14 |
15 | interface DateFnNameObj {
16 | [prop: string]: DateFnName;
17 | }
--------------------------------------------------------------------------------
/src/date/index.ts:
--------------------------------------------------------------------------------
1 | ///
2 | import { replace } from '../string/index';
3 |
4 | /**
5 | * @obj
6 | * @desc 操作日期的相关方法。所有函数不会改变实参的值,会返回操作后的结果。
7 | * @method createFormatDate - 传入日期格式,返回已毫秒数做参数的日期格式化函数。详情见本函数。
8 | */
9 | const date: DateModule = {
10 | /**
11 | * @func
12 | * @desc 格式化日期的函数。
13 | * @param {string} format - 需要的日期的格式。如:
14 | 'yy-MM-dd hh:mm:ss ww'(ww为星期,小写w为英文,大写W为中文)
15 | 'MM dd,yyyy hh:mm:ss'等等
16 | * @return {function} 返回一个需要传入毫秒数作为参数的函数。
17 | */
18 | createFormatDate: function (format: string = 'YYYY/MM/DD hh:mm'): (ms: number) => string {
19 | let replaceFormat = replace(/[a-zA-Z]+/g);
20 |
21 | return (ms: number): string => {
22 | const dateFunctions: DateFnNameObj = {
23 | 'Y': 'getFullYear',
24 | 'M': 'getMonth',
25 | 'D': 'getDate',
26 | 'h': 'getHours',
27 | 'm': 'getMinutes',
28 | 's': 'getSeconds',
29 | 'w': 'getDay',
30 | 'W': 'getDay'
31 | };
32 | const weeks: ArrayObject = {
33 | 'w': ['Sun.', 'Mon.', 'Tues.', 'Wed.', 'Thur.', 'Fri.', 'Sat.'],
34 | 'W': ['日', '一', '二', '三', '四', '五', '六'].map(week => `星期${week}`)
35 | };
36 | let date: Date = new Date(ms);
37 |
38 | return replaceFormat(format, (matchStr: string): string => {
39 | let dateFuncName: DateFnName | undefined = dateFunctions[matchStr[0]];
40 |
41 | if (dateFuncName) {
42 | if (dateFuncName === 'getMonth') {
43 | const str = `0000${date[dateFuncName]() + 1}`;
44 |
45 | return str.substring(str.length - matchStr.length);
46 | } else if (dateFuncName === 'getDay') {
47 | return weeks[matchStr[0]][date[dateFuncName]()];
48 | } else {
49 | const str = '0000' + date[dateFuncName]();
50 |
51 | return str.substring(str.length - matchStr.length);
52 | }
53 | } else {
54 | return matchStr;
55 | }
56 | });
57 | };
58 | }
59 | };
60 |
61 | export default date;
62 | export const createFormatDate = date.createFormatDate;
63 |
--------------------------------------------------------------------------------
/src/fn/__test__/index.test.ts:
--------------------------------------------------------------------------------
1 | import fn from '../index';
2 | const {
3 | curry,
4 | compose,
5 | debounce,
6 | throttle,
7 | } = fn;
8 |
9 | test('Currying.', () => {
10 | const add = (a: number, b: number, c: number): number => a + b + c;
11 | const curryAdd: any = curry(add);
12 |
13 | expect(curryAdd(1, 2, 3)).toBe(6);
14 | expect(curryAdd(1, 2)(3)).toBe(6);
15 | expect(curryAdd(1)(2)(3)).toBe(6);
16 | expect(curryAdd(1)(2, 3)).toBe(6);
17 | });
18 |
19 | test('Compose', () => {
20 | const plusOne = (num) => num * 1 + 1;
21 | const double = (num) => num * 2;
22 | const plusOneAndDouble = compose(double, plusOne);
23 |
24 | expect(plusOneAndDouble(1)).toBe(4);
25 | expect(plusOneAndDouble(2)).toBe(6);
26 | expect(plusOneAndDouble('2')).toBe(6);
27 | });
28 |
29 | describe('Debounce', () => {
30 | function plusOne(number: number) {
31 | return number + 1;
32 | }
33 |
34 | test('Immediate', (done) => {
35 | const executor = debounce(plusOne, 500, true);
36 | let result: number;
37 |
38 | result = executor.execute(1) as number;
39 | expect(result).toBe(2);
40 |
41 | setTimeout(function () {
42 | result = executor.execute(2) as number;
43 |
44 | expect(result).toBe(2);
45 | }, 200);
46 |
47 | setTimeout(function () {
48 | result = executor.result;
49 | expect(result).toBe(3);
50 | done();
51 | }, 800);
52 | });
53 |
54 | test('Delay.', function (done) {
55 | const executor = debounce(plusOne, 500, false);
56 | let result: number;
57 |
58 | result = executor.execute(1) as number;
59 | expect(result).toBe(null);
60 |
61 | setTimeout(function () {
62 | result = executor.execute(2) as number;
63 |
64 | expect(result).toBe(null);
65 | }, 200);
66 |
67 | setTimeout(function () {
68 | result = executor.result;
69 | expect(result).toBe(3);
70 | done();
71 | }, 800);
72 | });
73 | });
74 |
75 | describe('Throttle.', () => {
76 | function plusOne(number: number) {
77 | return number + 1;
78 | }
79 |
80 | test('Execute Twice', () => {
81 | const executor = throttle(plusOne, 300);
82 | let result: number;
83 |
84 | result = executor.execute(1);
85 | expect(result).toBe(2);
86 |
87 | setTimeout(function () {
88 | result = executor.execute(2);
89 | expect(result).toBe(2);
90 | }, 100);
91 |
92 | setTimeout(function () {
93 | expect(result).toBe(3);
94 | }, 400);
95 | });
96 |
97 | test('Execute Start', () => {
98 | const executor = throttle(plusOne, 300, {
99 | isExecuteAtStart: true,
100 | isExecuteAtEnd: false,
101 | });
102 | let result: number;
103 |
104 | result = executor.execute(1);
105 | expect(result).toBe(2);
106 |
107 | setTimeout(function () {
108 | result = executor.execute(2);
109 | expect(result).toBe(2);
110 | }, 100);
111 |
112 | setTimeout(function () {
113 | expect(result).toBe(2);
114 | }, 400);
115 | });
116 |
117 | test('Execute End', () => {
118 | const executor = throttle(plusOne, 300, {
119 | isExecuteAtStart: false,
120 | isExecuteAtEnd: true,
121 | });
122 | let result: number;
123 |
124 | result = executor.execute(1);
125 | expect(result).toBe(null);
126 |
127 | setTimeout(function () {
128 | result = executor.execute(2);
129 | expect(result).toBe(null);
130 | }, 100);
131 |
132 | setTimeout(function () {
133 | expect(result).toBe(3);
134 | }, 400);
135 | });
136 | });
--------------------------------------------------------------------------------
/src/fn/index.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @obj
3 | * @desc 操作函数的相关方法。所有函数不会改变实参的值,会返回操作后的结果。
4 | * @method curry - 将传入的函数柯里化
5 | * @method compose - 将所有传入的函数从右向左组合起来
6 | * @method debounce - 防抖
7 | * @method throttle - 节流
8 | */
9 | interface FunctionModule {
10 | curry: (fn: (...params: any[]) => Return) => CurryFunction;
11 | compose: (...fn: any[]) => (...params: any[]) => Return;
12 | /**
13 | *
14 | * @template Return
15 | * @param {(...params: any[]) => Return} fn 回调函数
16 | * @param {number} wait 等待时间
17 | * @param {boolean} immediate 是否立刻执行一次
18 | * @returns {(() => (Return | void))}
19 | */
20 | debounce: (
21 | fn: (...params: any[]) => Return,
22 | wait: number,
23 | immediate: boolean
24 | ) => Executor;
25 | throttle: (
26 | fn: (...params: any[]) => Return,
27 | wait: number,
28 | options?: ThrottleOptions
29 | ) => Executor;
30 | }
31 |
32 | interface CurryFunction {
33 | (...newParams: any[]): Return | CurryFunction
34 | }
35 |
36 | interface Executor {
37 | execute: (...params: any[]) => (Return | null);
38 | result: Return;
39 | }
40 |
41 | interface ThrottleOptions {
42 | isExecuteAtStart: boolean; // 是否执行开始函数
43 | isExecuteAtEnd: boolean;// 是否执行结尾函数
44 | }
--------------------------------------------------------------------------------
/src/fn/index.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | /**
4 | * @obj
5 | * @desc 操作函数的相关方法。所有函数不会改变实参的值,会返回操作后的结果。
6 | * @method curry - 将传入的函数柯里化
7 | * @method compose - 将所有传入的函数从右向左组合起来
8 | */
9 | const fn: FunctionModule = {
10 | curry: function (fn: Function): CurryFunction {
11 | let paramsLength: number = fn.length;
12 |
13 | function closure(params: any[]): CurryFunction {
14 |
15 | let wrapper: CurryFunction = function (...newParams: any[]) {
16 | let allParams = [...params, ...newParams];
17 |
18 | if (allParams.length < paramsLength) {
19 | return closure(allParams);
20 | } else {
21 | return fn.apply(null, allParams);
22 | }
23 | };
24 |
25 | return wrapper;
26 | }
27 |
28 | return closure([]);
29 | },
30 | compose: function (...fn: any[]): (...params: any[]) => Return {
31 | return (...params: any[]): Return => {
32 | let i = fn.length - 1;
33 | let result = fn[i].apply(null, params);
34 |
35 | while (--i >= 0) {
36 | result = fn[i](result);
37 | }
38 |
39 | return result;
40 | };
41 | },
42 | debounce: function (
43 | fn: (...params: any[]) => Return,
44 | wait: number,
45 | immediate: boolean
46 | ): Executor {
47 | const now: () => number = Date.now.bind(Date);
48 | let lastTime: number = 0;
49 | let timer: number = null;
50 | let params: IArguments = null;
51 | let _this: Function | null = null;
52 |
53 | function later(): void {
54 | const nowTime: number = now();
55 |
56 | if (nowTime - lastTime < wait) {
57 | const remainTime = wait - (nowTime - lastTime);
58 |
59 | timer = setTimeout(later, remainTime);
60 | } else {
61 | debouncer.result = fn.apply(_this, params);
62 |
63 | timer = null;
64 | _this = null;
65 | params = null;
66 | }
67 | }
68 |
69 | function execute(): (Return | null) {
70 | lastTime = now();
71 | _this = this;
72 | params = arguments;
73 |
74 | try {
75 | if (immediate && timer === null) {
76 | debouncer.result = fn.apply(_this, params);
77 | }
78 |
79 | return debouncer.result;
80 | } finally {
81 | if (timer === null) {
82 | timer = setTimeout(later, wait);
83 | }
84 | }
85 | }
86 |
87 | const debouncer: Executor = {
88 | execute,
89 | result: null,
90 | };
91 |
92 | return debouncer;
93 | },
94 | throttle: function (
95 | fn: (...params: any[]) => Return,
96 | wait: number,
97 | {
98 | isExecuteAtStart = true,
99 | isExecuteAtEnd = true,
100 | }: ThrottleOptions = {
101 | isExecuteAtStart: true,
102 | isExecuteAtEnd: true,
103 | }
104 | ): Executor {
105 | let timer: number = null;
106 | let _this: Function = null;
107 | let params: IArguments = null;
108 |
109 | function execute(): (Return | null) {
110 | _this = this;
111 | params = arguments;
112 |
113 | if (isExecuteAtStart && timer === null) {
114 | executor.result = fn.apply(_this, params);
115 | _this = null;
116 | params = null;
117 | }
118 |
119 | if (isExecuteAtEnd) {
120 | if (timer === null) {
121 | timer = setTimeout(function () {
122 | executor.result = fn.apply(_this, params);
123 | _this = null;
124 | params = null;
125 | timer = null;
126 | }, wait);
127 | }
128 | }
129 |
130 | return executor.result;
131 | }
132 |
133 | const executor: Executor = {
134 | execute,
135 | result: null
136 | };
137 |
138 | return executor;
139 | }
140 | };
141 |
142 | export default fn;
143 | export const curry = fn.curry;
144 | export const compose = fn.compose;
145 | export const debounce = fn.debounce;
146 | export const throttle = fn.throttle;
147 |
--------------------------------------------------------------------------------
/src/math/__test__/index.test.ts:
--------------------------------------------------------------------------------
1 | import math from '../index';
2 | const {
3 | createSin,
4 | createGetPointOnCircle,
5 | add,
6 | } = math;
7 |
8 | describe('Sin.', () => {
9 | test('Height = 2, Width = 2, Offset = PI/2', () => {
10 | const sin = createSin(2, 2, Math.PI / 2);
11 |
12 | expect(sin(Math.PI / 2)).toBe(-2);
13 | });
14 | });
15 |
16 | describe('Get point on the circle.', () => {
17 | test('Radius = 4, OffsetX = 10, offsetY = 5', () => {
18 | const getPointOnCircle = createGetPointOnCircle(4, 10, 5);
19 | let point = getPointOnCircle(0);
20 |
21 | expect(point.x).toBe(14);
22 | expect(point.y).toBe(5);
23 |
24 | point = getPointOnCircle(Math.PI / 2);
25 |
26 | expect(point.x).toBe(10);
27 | expect(point.y).toBe(9);
28 | });
29 | });
30 |
31 | test('Add', function () {
32 | expect(add(0.1, 0.2)).toBe(0.3);
33 | expect(add(0.1, 0.2, 0.2, 0.1)).toBe(0.6);
34 | expect(add(1, 1.0)).toBe(2);
35 | });
--------------------------------------------------------------------------------
/src/math/index.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @obj
3 | * @desc 数学相关函数
4 | * @method createSin - y=f(x)=height * sin(width * x + offset)
5 | * @method createGetPointOnCircle - 返回获取在圆上的点的函数
6 | */
7 | interface MathModule {
8 | createSin: (height: number, width: number, offset: number) => (x: number) => number;
9 | createGetPointOnCircle: (radius: number, offsetX: number, offsetY: number) => (radian: number) => Point;
10 | add: (...numbers: number[]) => number;
11 | }
12 |
13 | interface Point {
14 | x: number;
15 | y: number;
16 | }
17 |
--------------------------------------------------------------------------------
/src/math/index.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | const math: MathModule = {
4 | createSin: function (height: number, width: number, offset: number) {
5 | return (x: number): number => height * Math.sin(width * x + offset);
6 | },
7 | createGetPointOnCircle: function (radius: number, offsetX: number = 0, offsetY: number = 0) {
8 | return (radian: number) => ({
9 | x: offsetX + radius * Math.cos(radian),
10 | y: offsetY + radius * Math.sin(radian),
11 | });
12 | },
13 | add: function (...numbers: number[]): number {
14 | function getDecimalLength(n: number): number {
15 | const temp: string[] = n.toString().split('.');
16 |
17 | return temp[temp.length - 1].length;
18 | }
19 |
20 | function addTwoNumber(a: number, b: number): number {
21 | const firstLenth: number = getDecimalLength(a);
22 | const secondeLenth: number = getDecimalLength(a);
23 | const biggerLength: number = firstLenth > secondeLenth ? firstLenth : secondeLenth;
24 | const n: number = Math.pow(10, biggerLength);
25 |
26 | return (a * n + b * n) / n;
27 | }
28 |
29 | return numbers.reduce((previous, current) => {
30 | return addTwoNumber(previous, current);
31 | });
32 | },
33 | };
34 |
35 | export default math;
36 | export const createSin = math.createSin;
37 | export const createGetPointOnCircle = math.createGetPointOnCircle;
38 | export const add = math.add;
39 |
--------------------------------------------------------------------------------
/src/net/__test__/index.test.ts:
--------------------------------------------------------------------------------
1 | import net from '../index';
2 | import object from '../../object/index';
3 | const {
4 | parseUrl,
5 | parseParams,
6 | } = net;
7 |
8 | test('Parse URL', () => {
9 | const URL = 'https://github.com/MrWindlike/Windlike-Utils?key=value';
10 | const result = parseUrl(URL);
11 |
12 | expect(
13 | object.deepCompare(
14 | result,
15 | {
16 | url: URL,
17 | host: 'https://github.com',
18 | port: 80,
19 | path: '/MrWindlike/Windlike-Utils',
20 | params: {
21 | key: 'value',
22 | },
23 | }
24 | )
25 | ).toBeTruthy();
26 | });
27 |
28 | test('Parse params.', () => {
29 | const SEARCH = '?key=value&search=windlike';
30 | const result = parseParams(SEARCH);
31 |
32 | expect(
33 | object.deepCompare(
34 | result,
35 | {
36 | key: 'value',
37 | search: 'windlike',
38 | },
39 | )
40 | ).toBeTruthy();
41 | });
42 |
--------------------------------------------------------------------------------
/src/net/index.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @obj
3 | * @desc desc
4 | * @method parseParams - 解析URL的参数部分的函数
5 | * @method parseUrl - 解析URL的函数
6 | */
7 | interface NetModule {
8 | parseParams: (locationSearch: string) => object;
9 | parseUrl: (url: string) => UrlInfoObject;
10 | }
11 |
12 | interface UrlInfoObject {
13 | url: string
14 | host: string
15 | port: number
16 | path: string
17 | params: object
18 | }
19 |
--------------------------------------------------------------------------------
/src/net/index.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | import string from '../string/index';
4 | import array from '../array/index';
5 | import fn from '../fn/index';
6 |
7 | /**
8 | * @obj
9 | * @desc desc
10 | * @method parseParams - 解析URL的参数部分的函数
11 | * @method parseUrl - 解析URL的函数
12 | */
13 | const net: NetModule = {
14 | parseParams: function (locationSearch: string): object {
15 | let first = (arr: any[]) => arr[0];
16 | let last = (arr: any[]) => arr[arr.length - 1];
17 | let hasQuestionMark = (locationSearch: string) => locationSearch.includes('?') ? locationSearch : `?${locationSearch}`;
18 | let separateOutParams = fn.compose(last, string.split('?'), hasQuestionMark);
19 | let groupingParams: (paramsStr: string) => string[][] = fn.compose(array.map(string.split('=')), string.split('&'));
20 | let getParams = (paramsArr: string[][]) => {
21 | let params: any = {};
22 |
23 | paramsArr.forEach((param: string[]) => {
24 | if (first(param)) {
25 | params[first(param)] = last(param);
26 | }
27 | });
28 |
29 | return params;
30 | };
31 |
32 | let paramsStr: string = separateOutParams(locationSearch);
33 | let paramsArr: string[][] = groupingParams(paramsStr);
34 | let params: object = getParams(paramsArr);
35 |
36 | return params;
37 | },
38 | parseUrl: function (url: string): UrlInfoObject {
39 | const HOST_PORT_REGEXP = /^(http:\/\/|https:\/\/)[0-9a-zA-Z.:]+/;
40 | const HOST_REGEXP = /^(http:\/\/|https:\/\/)[0-9a-zA-Z.]+/;
41 |
42 | /* function */
43 | let first = (arr: any[]) => arr[0];
44 | let last = (arr: any[]) => arr[arr.length - 1];
45 | let checkPort = (port: string) => port ? port : 80;
46 | let checkPath = (path: string) => path ? path : '/';
47 | let checkParams = (url: string) => url.includes('?') ? url : '';
48 | let separateOutHref: Fn = fn.compose(first, string.split('?'));
49 | let separateOutParams: Fn = fn.compose(last, string.split('?'), checkParams);
50 | let matchHost: Fn = fn.compose(first, string.match(HOST_PORT_REGEXP));
51 | let groupingParams: (paramsStr: string) => string[][] = fn.compose(array.map(string.split('=')), string.split('&'));
52 | let getParams = (paramsArr: string[][]) => {
53 | let params: ArrayObject = {};
54 |
55 | paramsArr.forEach((param: string[]) => {
56 | if (first(param)) {
57 | params[first(param)] = last(param);
58 | }
59 | });
60 |
61 | return params;
62 | };
63 | let getHost: Fn = fn.compose(first, string.match(HOST_REGEXP));
64 | let getPort: (host: string) => Fn = (host: string) => fn.compose(checkPort, last, string.split(':'), last, string.split(host));
65 |
66 | /* var */
67 | let href: string = separateOutHref(url);
68 | let paramsStr: string = separateOutParams(url);
69 | let hostWithPort: string = matchHost(href);
70 | let host: string = getHost(hostWithPort);
71 | let port: number = getPort(host)(hostWithPort);
72 | let path: string = fn.compose(checkPath, last, string.split(hostWithPort))(href);
73 | let paramsArr: string[][] = groupingParams(paramsStr);
74 | let params: object = getParams(paramsArr);
75 | const urlMsg: UrlInfoObject = { url, host, port, path, params };
76 |
77 | return urlMsg;
78 | }
79 | };
80 |
81 | export default net;
82 | export const parseParams = net.parseParams;
83 | export const parseUrl = net.parseUrl;
84 |
--------------------------------------------------------------------------------
/src/number/__test__/index.test.ts:
--------------------------------------------------------------------------------
1 | import number from '../index';
2 | const {
3 | createRandomFunction,
4 | } = number;
5 |
6 | describe('Create a random number.', () => {
7 | test('Int between 1 to 100.', () => {
8 | const createRandom = createRandomFunction(100, 1, false);
9 | const result = createRandom();
10 |
11 | expect(result).toBeGreaterThan(0);
12 | expect(result).toBeLessThan(101);
13 | expect(result).toBe(Math.floor(result));
14 | });
15 |
16 | test('Float between 1 to 100. ', () => {
17 | const createRandom = createRandomFunction(100, 1, true);
18 | const result = createRandom();
19 |
20 | expect(result).toBeGreaterThan(0);
21 | expect(result).toBeLessThan(101);
22 | });
23 | });
--------------------------------------------------------------------------------
/src/number/index.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @obj
3 | * @desc 数字的相关方法。所有函数不会改变实参的值,会返回操作后的结果。
4 | * @method createRandomFunction - 返回一个可以产生符合条件的随机数的函数
5 | */
6 | interface NumberModule {
7 | createRandomFunction: (min: number, max: number, float: boolean) => () => number;
8 | }
9 |
--------------------------------------------------------------------------------
/src/number/index.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | /**
4 | * @obj
5 | * @desc 数字的相关方法。所有函数不会改变实参的值,会返回操作后的结果。
6 | * @method random - 返回一个可以产生符合条件的随机数的函数
7 | */
8 | const number: NumberModule = {
9 | createRandomFunction: function (min: number = 0, max: number, float: boolean): () => number {
10 | return (): number => {
11 | if (min > max) {
12 | [min, max] = [max, min];
13 | }
14 | if (float || min % 1 || max % 1) {
15 | return min + Math.random() * (max - min);
16 | }
17 |
18 | return min + Math.floor(Math.random() * (max - min + 1));
19 | };
20 | }
21 | };
22 |
23 | export default number;
24 | export const createRandomFunction = number.createRandomFunction;
25 |
--------------------------------------------------------------------------------
/src/object/__test__/index.test.ts:
--------------------------------------------------------------------------------
1 | import object from '../index';
2 | const { shallowCompare, deepCompare, has } = object;
3 |
4 | describe('Shallow compare.', () => {
5 | test('Equal.', () => {
6 | const obj = {
7 | key: 'value',
8 | a: 1,
9 | b: 2
10 | };
11 | const anotherObj = {
12 | a: 1,
13 | key: 'value',
14 | b: 2
15 | };
16 |
17 | expect(shallowCompare(obj, anotherObj)).toBeTruthy();
18 | });
19 |
20 | test('Not Equal.', () => {
21 | const obj = {
22 | key: 'value',
23 | a: 1,
24 | b: 2
25 | };
26 |
27 | expect(shallowCompare(obj, {
28 | a: 1,
29 | b: 2,
30 | child: {}
31 | })).toBeFalsy();
32 | expect(shallowCompare(obj, {
33 | a: 1,
34 | b: 2,
35 | child: {}
36 | })).toBeFalsy();
37 | });
38 | });
39 |
40 | describe('Is two object\'s values equal?', () => {
41 | test('Yes.', () => {
42 | expect(
43 | deepCompare(
44 | {
45 | a: 1,
46 | b: 2
47 | },
48 | {
49 | b: 2,
50 | a: 1
51 | }
52 | )
53 | ).toBeTruthy();
54 | expect(
55 | deepCompare(
56 | {
57 | a: 1,
58 | child: {
59 | key: 'value'
60 | },
61 | b: 2,
62 | obj: {},
63 | none: null
64 | },
65 | {
66 | b: 2,
67 | obj: {},
68 | none: null,
69 | a: 1,
70 | child: {
71 | key: 'value'
72 | }
73 | }
74 | )
75 | ).toBeTruthy();
76 | });
77 |
78 | test('No.', () => {
79 | expect(
80 | deepCompare(
81 | {
82 | a: 1,
83 | b: 2
84 | },
85 | {
86 | a: 1,
87 | b: '2'
88 | }
89 | )
90 | ).toBeFalsy();
91 |
92 | expect(
93 | deepCompare(
94 | {
95 | a: 1,
96 | b: 2,
97 | child: {}
98 | },
99 | {
100 | b: 2,
101 | a: 1,
102 | child: {
103 | key: 'value'
104 | }
105 | }
106 | )
107 | ).toBeFalsy();
108 | });
109 | });
110 |
111 | describe('Is object has this key?', () => {
112 | const object = { key: 'value', nonexistent: undefined };
113 |
114 | test('Yes.', () => {
115 | const result = has(object, 'key');
116 |
117 | expect(result).toBeTruthy();
118 | });
119 |
120 | test('Yes.', () => {
121 | const result = has(object, 'nonexistent');
122 |
123 | expect(result).toBeFalsy();
124 | });
125 | });
126 |
--------------------------------------------------------------------------------
/src/object/index.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @obj
3 | * @desc 操作对象的相关方法。所有函数不会改变实参的值,会返回操作后的结果。
4 | * @method valueEqual - 判断两个对象的值是否相等
5 | */
6 | interface ObjectModule {
7 | shallowCompare: (firstObj: AnyObject, secondObj: AnyObject) => boolean;
8 | deepCompare: (firstObj: AnyObject, secondObj: AnyObject) => boolean;
9 | has: (object: AnyObject, key: string) => boolean;
10 | }
11 |
--------------------------------------------------------------------------------
/src/object/index.ts:
--------------------------------------------------------------------------------
1 | ///
2 | /**
3 | * @obj
4 | * @desc 操作对象的相关方法。所有函数不会改变实参的值,会返回操作后的结果。
5 | * @method valueEqual - 判断两个对象的值是否相等
6 | */
7 | let _this: ObjectModule = null;
8 | const object: ObjectModule = (_this = {
9 | shallowCompare: function (firstObj: AnyObject, secondObj: AnyObject): boolean {
10 | for (let key in firstObj) {
11 | if (
12 | !firstObj.hasOwnProperty(key) ||
13 | !secondObj.hasOwnProperty(key) ||
14 | firstObj[key] !== secondObj[key]
15 | ) {
16 | return false;
17 | }
18 | }
19 |
20 | return true;
21 | },
22 | deepCompare: function (firstObj: AnyObject, secondObj: AnyObject): boolean {
23 | const firstEntries: any[] = Object.entries(firstObj);
24 | const secondEntries: any[] = Object.entries(secondObj);
25 |
26 | if (firstEntries.length !== secondEntries.length) {
27 | return false;
28 | }
29 |
30 | for (let [key] of firstEntries) {
31 | const firstValue = firstObj[key];
32 | const secondValue = secondObj[key];
33 |
34 | if (typeof firstValue !== typeof secondValue) {
35 | return false;
36 | } else if (typeof firstValue === 'object' && firstValue !== null) {
37 | if (!_this.deepCompare(firstValue, secondValue)) {
38 | return false;
39 | }
40 | } else {
41 | if (firstValue !== secondValue) {
42 | return false;
43 | }
44 | }
45 | }
46 |
47 | return true;
48 | },
49 | has: function (object: AnyObject, key: string): boolean {
50 | return object[key] !== undefined;
51 | }
52 | });
53 |
54 | export default object;
55 | export const shallowCompare = object.shallowCompare;
56 | export const deepCompare = object.deepCompare;
57 | export const has = object.has;
58 |
--------------------------------------------------------------------------------
/src/string/__test__/index.test.ts:
--------------------------------------------------------------------------------
1 | import string from '../index';
2 | import array from '../../array/index';
3 | const {
4 | replace,
5 | split,
6 | match,
7 | } = string;
8 |
9 | test('Replace string.', () => {
10 | const str = 'I\'m Windlike.';
11 | const replaceWindlike = replace('Windlike');
12 |
13 | expect(replaceWindlike(str, 'I')).toBe('I\'m I.');
14 | expect(replaceWindlike(str, 'Wind')).toBe('I\'m Wind.');
15 | });
16 |
17 | test('Split string.', () => {
18 | const str = 'I And You';
19 | const splitStr = split(' ');
20 | const result = splitStr(str);
21 |
22 | expect(result[0]).toBe('I');
23 | expect(result[1]).toBe('And');
24 | expect(result[2]).toBe('You');
25 | });
26 |
27 | test('Match string.', () => {
28 | const re = /[\w]+/g;
29 | const str = 'I am a string.';
30 | const matchWork = match(re);
31 | const result = matchWork(str);
32 |
33 | expect(array.shallowCompare(result, ['I', 'am', 'a', 'string'])).toBeTruthy();
34 |
35 | });
36 |
37 |
--------------------------------------------------------------------------------
/src/string/index.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @obj
3 | * @desc 操作字符串的相关方法。所有函数不会改变实参的值,会返回操作后的结果。
4 | * @method replace - 传入匹配规则参数,返回一个符合改匹配规则的函数
5 | * @method split - 返回分割该字符的函数
6 | * @method match - 返回匹配该正则的函数
7 | */
8 | interface StringModule {
9 | replace: (match: RegExp | string) => (str: string, substitute: any) => string;
10 | split: (char: string | RegExp) => (str: string) => string[];
11 | match: (regexp: RegExp) => (str: string) => string[];
12 | }
13 |
--------------------------------------------------------------------------------
/src/string/index.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | /**
4 | * @obj
5 | * @desc 操作字符串的相关方法。所有函数不会改变实参的值,会返回操作后的结果。
6 | * @method replace - 传入匹配规则参数,返回一个符合改匹配规则的函数
7 | * @method split - 返回分割该字符的函数
8 | * @method match - 返回匹配该正则的函数
9 | */
10 | let _this: StringModule = null;
11 | export const string: StringModule = _this = {
12 | replace: function (match: RegExp | string): (str: string, substitute: any) => string {
13 | return (str: string, substitute: any) => str.replace(match, substitute);
14 | },
15 | split: function (char: string | RegExp): (str: string) => string[] {
16 | return (str: string): string[] => str.split(char);
17 | },
18 | match: function (regexp: RegExp): (str: string) => string[] {
19 | return (str: string): string[] => str.match(regexp);
20 | }
21 | };
22 |
23 | export default string;
24 | export const replace = string.replace;
25 | export const split = string.split;
26 | export const match = string.match;
27 |
--------------------------------------------------------------------------------
/src/utils.d.ts:
--------------------------------------------------------------------------------
1 | declare interface ArrayObject {
2 | [prop: string]: any[];
3 | }
4 |
5 | declare interface StringObject {
6 | [prop: string]: string;
7 | }
8 |
9 | declare interface AnyObject extends Object {
10 | [prop: string]: any;
11 | }
12 |
13 | declare interface Fn {
14 | (...params: any[]): Return;
15 | }
16 |
--------------------------------------------------------------------------------
/src/utils.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | import array from './array/index';
4 | import date from './date/index';
5 | import fn from './fn/index';
6 | import math from './math/index';
7 | import number from './number/index';
8 | import net from './net/index';
9 | import object from './object/index';
10 | import string from './string/index';
11 | import verification from './verification/index';
12 |
13 | /**
14 | * @obj
15 | * @desc 工具实例。部分函数使用到ES6的语法,请确保你的浏览器支持。
16 | * @part array - 数组
17 | * @part date - 日期
18 | * @part fn - 函数
19 | * @part math - 数学
20 | * @part number - 数字
21 | * @part net - 网络
22 | * @part object - 对象
23 | * @part string - 字符串
24 | * @part verification - 验证
25 | */
26 | export const utils = { array, date, fn, math, number, net, object, string, verification };
27 | export default utils;
28 | export { array, date, fn, math, number, net, object, string, verification };
29 |
--------------------------------------------------------------------------------
/src/verification/__test__/index.test.ts:
--------------------------------------------------------------------------------
1 | import verification from '../index';
2 | const {
3 | check,
4 | checkLength,
5 | checkRe,
6 | } = verification;
7 |
8 | test('Check RegExp.', () => {
9 | const checkFunction = checkRe(/<[\s\S]*?(script)[\s\S]*?>/);
10 |
11 | expect(checkFunction('')).toBeTruthy();
12 | expect(checkFunction('')).toBeTruthy();
13 | expect(checkFunction('')).toBeTruthy();
14 | expect(checkFunction('')).toBeFalsy();
15 | });
16 |
17 | test('Check string\'s length.', () => {
18 | const checkLengthFunction = checkLength(1, 5);
19 |
20 | expect(checkLengthFunction('windlike')).toBeFalsy();
21 | expect(checkLengthFunction('wind')).toBeTruthy();
22 | });
23 |
24 | describe('Check common type.', () => {
25 | test('Phone.', () => {
26 | const checkPhone = check('phone');
27 |
28 | expect(checkPhone('13800000000')).toBeTruthy();
29 | expect(checkPhone('12345678909')).toBeFalsy();
30 | });
31 |
32 | test('Phone.', () => {
33 | const checkEmail = check('email');
34 |
35 | expect(checkEmail('windlike@windlike.com')).toBeTruthy();
36 | expect(checkEmail('windlike.com')).toBeFalsy();
37 | });
38 | });
--------------------------------------------------------------------------------
/src/verification/index.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @obj
3 | * @desc 验证的相关方法。所有函数不会改变实参的值,会返回操作后的结果。
4 | * @method checkRe - 返回验证是否匹配该正则的函数
5 | * @method checkLength - 返回验证是否匹配长度的函数
6 | * @method check - 返回验证是否匹配该类型的函数
7 | */
8 | interface VerificationModule {
9 | readonly _phoneRE: RegExp;
10 | readonly _emailRE: RegExp;
11 |
12 | checkRe: (re: RegExp) => (checkedStr: string) => boolean;
13 | checkLength: (min: number, max: number) => (str: string) => boolean;
14 | check: (checkType: CheckType) => (checkedStr: string) => boolean;
15 | [prop: string]: any
16 | }
17 |
18 | type CheckType = 'phone' | 'email';
19 |
--------------------------------------------------------------------------------
/src/verification/index.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | /**
4 | * @obj
5 | * @desc 验证的相关方法。所有函数不会改变实参的值,会返回操作后的结果。
6 | * @method checkRe - 返回验证是否匹配该正则的函数
7 | * @method checkLength - 返回验证是否匹配长度的函数
8 | * @method check - 返回验证是否匹配该类型的函数
9 | */
10 | let _this: VerificationModule = null;
11 | export const verification: VerificationModule = _this = {
12 | _phoneRE: /^(13[0-9]|15[012356789]|18[0-9]|17[678]|14[57])[0-9]{8}$/,
13 | _emailRE: /^([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/,
14 |
15 | checkRe: function (re: RegExp): (checkedStr: string) => boolean {
16 | return (checkedStr: string): boolean => {
17 | return re.test(checkedStr);
18 | };
19 | },
20 | checkLength: function (min: number = 0, max: number): (str: string) => boolean {
21 | return (str: string): boolean => str.length >= min && str.length <= max;
22 | },
23 | check: function (checkType: CheckType): (checkedStr: string) => boolean {
24 | return _this.checkRe(_this[`_${checkType}RE`]);
25 | }
26 | };
27 |
28 | export default verification;
29 | export const checkRe = verification.checkRe;
30 | export const checkLength = verification.checkLength;
31 | export const check = verification.check;
32 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./dist/",
4 | "sourceMap": true,
5 | "noImplicitAny": true,
6 | "module": "commonjs",
7 | "target": "es5",
8 | "lib": [
9 | "es2017",
10 | "es2015.core",
11 | "dom",
12 | ]
13 | },
14 | "include": [
15 | "./src/*"
16 | ]
17 | }
--------------------------------------------------------------------------------