@ezez/utils 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -8
- package/README.md +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/isEmpty.js +1 -1
- package/dist/isEmpty.js.map +1 -1
- package/dist/isNumericString.d.ts +10 -0
- package/dist/isNumericString.d.ts.map +1 -0
- package/dist/isNumericString.js +61 -0
- package/dist/isNumericString.js.map +1 -0
- package/dist/occurrences.d.ts +7 -0
- package/dist/occurrences.d.ts.map +1 -0
- package/dist/occurrences.js +27 -0
- package/dist/occurrences.js.map +1 -0
- package/docs/assets/search.js +1 -1
- package/docs/functions/cap.html +9 -5
- package/docs/functions/capitalize.html +9 -5
- package/docs/functions/coalesce.html +9 -5
- package/docs/functions/ensureArray.html +9 -5
- package/docs/functions/ensureError.html +9 -5
- package/docs/functions/get.html +9 -5
- package/docs/functions/getMultiple.html +9 -5
- package/docs/functions/insertSeparator.html +9 -5
- package/docs/functions/isEmpty.html +9 -5
- package/docs/functions/isNumericString.html +117 -0
- package/docs/functions/isPlainObject.html +9 -5
- package/docs/functions/last.html +9 -5
- package/docs/functions/mapAsync.html +9 -5
- package/docs/functions/mapValues.html +9 -5
- package/docs/functions/match.html +9 -5
- package/docs/functions/merge.html +17 -13
- package/docs/functions/mostFrequent.html +9 -5
- package/docs/functions/noop.html +9 -5
- package/docs/functions/occurrences.html +129 -0
- package/docs/functions/omit.html +9 -5
- package/docs/functions/pick.html +9 -5
- package/docs/functions/pull.html +9 -5
- package/docs/functions/remove.html +9 -5
- package/docs/functions/rethrow.html +9 -5
- package/docs/functions/scale.html +9 -5
- package/docs/functions/seq.html +9 -5
- package/docs/functions/seqEarlyBreak.html +9 -5
- package/docs/functions/set.html +9 -5
- package/docs/functions/setImmutable.html +9 -5
- package/docs/functions/sortBy.html +9 -5
- package/docs/functions/throttle.html +9 -5
- package/docs/functions/truthy.html +9 -5
- package/docs/functions/wait.html +9 -5
- package/docs/functions/waitFor.html +9 -5
- package/docs/functions/waitSync.html +9 -5
- package/docs/index.html +10 -4
- package/docs/interfaces/GetMultipleSource.html +9 -5
- package/docs/interfaces/GetSource.html +9 -5
- package/docs/interfaces/IsNumericStringOptions.html +90 -0
- package/docs/interfaces/OccurencesOptions.html +71 -0
- package/docs/interfaces/SetImmutableSource.html +9 -5
- package/docs/interfaces/SetSource.html +9 -5
- package/docs/interfaces/ThrottleOptions.html +7 -7
- package/docs/interfaces/ThrottledFunctionExtras.html +7 -7
- package/docs/modules.html +12 -4
- package/docs/pages/Introduction.html +8 -4
- package/docs/types/MapValuesFn.html +9 -5
- package/docs/types/MatchCallback.html +9 -5
- package/docs/types/SeqEarlyBreaker.html +9 -5
- package/docs/types/SeqFn.html +9 -5
- package/docs/types/SeqFunctions.html +9 -5
- package/docs/types/SetImmutablePath.html +9 -5
- package/docs/types/ThrottledFunction.html +9 -5
- package/docs/variables/mapValuesUNSET.html +9 -5
- package/docs/variables/mergeUNSET.html +9 -5
- package/esm/index.d.ts +2 -0
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +2 -0
- package/esm/index.js.map +1 -1
- package/esm/isEmpty.js +1 -1
- package/esm/isEmpty.js.map +1 -1
- package/esm/isNumericString.d.ts +10 -0
- package/esm/isNumericString.d.ts.map +1 -0
- package/esm/isNumericString.js +58 -0
- package/esm/isNumericString.js.map +1 -0
- package/esm/occurrences.d.ts +7 -0
- package/esm/occurrences.d.ts.map +1 -0
- package/esm/occurrences.js +24 -0
- package/esm/occurrences.js.map +1 -0
- package/package.json +1 -1
- package/src/index.ts +2 -0
- package/src/isEmpty.ts +1 -1
- package/src/isNumericString.spec.ts +100 -0
- package/src/isNumericString.ts +94 -0
- package/src/occurrences.spec.ts +20 -0
- package/src/occurrences.ts +53 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
interface Options {
|
|
2
|
+
allowFloats?: boolean;
|
|
3
|
+
allowExponents?: boolean;
|
|
4
|
+
allowInfinity?: boolean;
|
|
5
|
+
allowNaN?: boolean;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const NOT_FOUND = -1;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Checks if a string is a numeric string. By default, it allows only integers. Floats and exponents can be enabled with
|
|
12
|
+
* options. Optionally allow NaN and Infinity.
|
|
13
|
+
* @param {string} string - String to check
|
|
14
|
+
* @param {object} [options] - Options object
|
|
15
|
+
* @param {boolean} [options.allowFloats=false] - Allow floats
|
|
16
|
+
* @param {boolean} [options.allowExponents=false] - Allow exponents
|
|
17
|
+
* @param {boolean} [options.allowInfinity=false] - Allow Initity and -Infinity (casing matters)
|
|
18
|
+
* @param {boolean} [options.allowNaN=false] - Allow NaN (casing matters)
|
|
19
|
+
*/
|
|
20
|
+
const isNumericString = (string: string, options: Options = {}) => { // eslint-disable-line max-statements, max-lines-per-function, max-len
|
|
21
|
+
if (typeof string !== "string") {
|
|
22
|
+
throw new TypeError("Expected a string");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (options.allowNaN && string === "NaN") {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (options.allowInfinity && (string === "Infinity" || string === "-Infinity")) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let normalized = string.toLowerCase();
|
|
34
|
+
if (normalized.startsWith("-")) {
|
|
35
|
+
normalized = normalized.slice(1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const parts = normalized.split(".");
|
|
39
|
+
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
|
41
|
+
if (parts.length > (options.allowFloats ? 2 : 1)) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const expParts = parts[parts.length - 1].split("e");
|
|
46
|
+
|
|
47
|
+
if (!options.allowExponents) {
|
|
48
|
+
if (expParts.length > 1) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
|
54
|
+
if (expParts.length > 2) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const hasPlusAt = normalized.indexOf("+");
|
|
60
|
+
if (hasPlusAt > NOT_FOUND) {
|
|
61
|
+
if (!options.allowExponents) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
if (hasPlusAt !== normalized.lastIndexOf("+")) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
if (hasPlusAt !== normalized.indexOf("e") + 1) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const hasMinusAt = normalized.indexOf("-");
|
|
73
|
+
if (hasMinusAt > NOT_FOUND) {
|
|
74
|
+
if (!options.allowExponents) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
if (hasMinusAt !== normalized.lastIndexOf("-")) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
if (hasMinusAt !== normalized.indexOf("e") + 1) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return Boolean(/^[\de.+-]+$/.exec(normalized));
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export {
|
|
89
|
+
isNumericString,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export type {
|
|
93
|
+
Options as IsNumericStringOptions,
|
|
94
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { occurrences } from "./occurrences.js";
|
|
2
|
+
|
|
3
|
+
describe("occurrences", function() {
|
|
4
|
+
it("returns zero for empty search string", function() {
|
|
5
|
+
occurrences("test string", "").must.equal(0);
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
it("returns count of occurences for typical use cases", function() {
|
|
9
|
+
occurrences("hello beautiful world, hello bees and hello sun", "hello").must.equal(3);
|
|
10
|
+
occurrences("hello beautiful world, hello bees and hello sun", "o").must.equal(4);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it("allows counting overlaps too", function() {
|
|
14
|
+
occurrences("aaaa", "aa", { overlap: true }).must.equal(3);
|
|
15
|
+
occurrences("aaaa", "aa", { overlap: false }).must.equal(2);
|
|
16
|
+
|
|
17
|
+
occurrences("aaaaaa", "aa", { overlap: true }).must.equal(5);
|
|
18
|
+
occurrences("aaaaaa", "aa", { overlap: false }).must.equal(3);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
interface Options {
|
|
2
|
+
/**
|
|
3
|
+
* Allow overlapping matches, ie. "aa" in "aaa" will return 2 instead of 1
|
|
4
|
+
*/
|
|
5
|
+
overlap?: boolean;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const NOT_FOUND = -1;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Count the number of occurrences of a substring in a string
|
|
12
|
+
*
|
|
13
|
+
* @example occurrences("aaa", "a"); // 3
|
|
14
|
+
* @example occurrences("aaaa", "aa", { overlap: false }); // 2
|
|
15
|
+
* @example occurrences("aaaa", "aa", { overlap: true }); // 3
|
|
16
|
+
* @param {string} string - string to search in
|
|
17
|
+
* @param {string} search - string to search for
|
|
18
|
+
* @param {object} [options] - options
|
|
19
|
+
* @param {boolean} [options.overlap=false] - allow overlapping matches, ie "aa" in "aaa" will return 2 instead of 1
|
|
20
|
+
*/
|
|
21
|
+
const occurrences = (string: string, search: string, { overlap }: Options = {}) => {
|
|
22
|
+
if (typeof string !== "string") {
|
|
23
|
+
throw new TypeError("Expected a string");
|
|
24
|
+
}
|
|
25
|
+
if (typeof search !== "string") {
|
|
26
|
+
throw new TypeError("Expected a string");
|
|
27
|
+
}
|
|
28
|
+
if (search.length === 0) {
|
|
29
|
+
return 0;
|
|
30
|
+
}
|
|
31
|
+
let n = 0,
|
|
32
|
+
i = 0;
|
|
33
|
+
|
|
34
|
+
// eslint-disable-next-line no-constant-condition,@typescript-eslint/no-unnecessary-condition
|
|
35
|
+
while (true) {
|
|
36
|
+
i = string.indexOf(search, i);
|
|
37
|
+
|
|
38
|
+
if (i === NOT_FOUND) {
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
n++;
|
|
42
|
+
i += overlap ? 1 : search.length;
|
|
43
|
+
}
|
|
44
|
+
return n;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export {
|
|
48
|
+
occurrences,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export type {
|
|
52
|
+
Options as OccurencesOptions,
|
|
53
|
+
};
|